如何使用 Graphviz 将节点放置在其他节点之上?
How to place nodes on top of others with Graphviz?
我正在尝试设计一种具有特定颜色和形状的非常特定类型的图表,但我无法判断这是否可以通过 Graphviz 实现。
我的目标是绘制一个有向图,其中每个节点:
- 由 3 个水平排列的小方框组成(
striped
rectangle
或 record
、rounded
)
- 相应地包含 3
labels
- 填充渐变
- 有一个黑色方形节点位于中间框的顶部
示例(所有黑框都已手动放置):
我已经达到了第三个要求,但我正在努力执行最后一个要求。您如何将方形节点(rect
、square
、box
等)放置在第一组节点(彩色矩形)的顶部,以便它们完全适合中间框的尺寸他们是为了掩盖?使用 Graphviz 甚至可能吗?
示例代码 (Python):
from graphviz import Digraph
# Dictionary storing relations between nodes
d = {0: set([1, 2, 3]),
1: set([4, 5, 6]),
2: set([7, 8, 9, 10]),
3: set([0]),
4: set([]),
5: set([]),
6: set([]),
7: set([]),
8: set([0]),
9: set([]),
10: set([])}
# List of node labels (3 labels per node)
P = [('S', 'M', 'S'),
('M', 'S', 'L'),
('M', 'S', 'S'),
('M', 'S', 'M'),
('S', 'L', 'L'),
('S', 'L', 'M'),
('S', 'L', 'X'),
('S', 'S', 'S'),
('S', 'S', 'M'),
('S', 'S', 'L'),
('S', 'S', 'X')]
# Dictionary storing the colors corresponding to each label
c = {'S':'olivedrab1',
'M':'mediumturquoise',
'L':'deepskyblue',
'X':'palevioletred1'}
# Create a "directed graph" with general node and edge attributes
G = Digraph(node_attr={'shape':'record',
'style':'rounded, filled',
'color':'white',
'height':'0.1',
'fontcolor':'white'},
edge_attr={'color':'grey',
'arrowhead':'vee'}
)
G.attr('graph', bgcolor='transparent')
# 1st pass: create all nodes (0 to 10)
for k in d:
l1, l2, l3 = P[k]
# set specific attribute to each node (label & colors)
G.attr('node', label='{} | {} | {}'.format(l1, ' ', l2), fillcolor='{}:{}'.format(c[l1], c[l2]))
G.node(str(k))
# 2nd pass: create edges between nodes
for k in d:
l1, l2, l3 = P[k]
for i in d[k]:
if i in d:
G.edge(str(k), str(i))
# Then, how to overlap black square nodes ?
我认为在 dot/graphviz 中不可能强制节点将一个节点叠加到另一个节点上;我想这会打败视觉渲染图形的全部意义。
此代码对节点使用 HTML(-like)形状;这些描述了一个三单元格 table,左侧和右侧具有渐变颜色,中间为纯黑色和白色文本。
import graphviz
# Dictionary storing relations between nodes
d = {0: set([1, 2, 3]),
1: set([4, 5, 6]),
2: set([7, 8, 9, 10]),
3: set([0]),
4: set([]),
5: set([]),
6: set([]),
7: set([]),
8: set([0]),
9: set([]),
10: set([])}
# List of node labels (3 labels per node)
P = [('S', 'M', 'S'),
('M', 'S', 'L'),
('M', 'S', 'S'),
('M', 'S', 'M'),
('S', 'L', 'L'),
('S', 'L', 'M'),
('S', 'L', 'X'),
('S', 'S', 'S'),
('S', 'S', 'M'),
('S', 'S', 'L'),
('S', 'S', 'X')]
# Dictionary storing the colors corresponding to each label
c = {'S':'olivedrab1:grey',
'M':'mediumturquoise:gray',
'L':'deepskyblue:gray',
'X':'palevioletred1:gray'}
# Create a "directed graph" with general node and edge attributes
G = graphviz.Digraph(
format='svg'
,edge_attr={'color':'grey',
'arrowhead':'vee'}
)
G.attr('graph', bgcolor='transparent')
# 1st pass: create all nodes (0 to 10)
for k in d:
l1, l2, l3 = P[k]
G.node(name=str(k),shape='plain',label=f'''<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR>
<TD BGCOLOR="{c[l1]}" GRADIENTANGLE="45">{l1}</TD>
<TD BGCOLOR="black"><FONT COLOR="white">{l2}</FONT></TD>
<TD BGCOLOR="{c[l3]}" GRADIENTANGLE="135">{l3}</TD>
</TR>
</TABLE>
>
'''
)
# 2nd pass: create edges between nodes
for k in d:
l1, l2, l3 = P[k]
for i in d[k]:
if i in d:
G.edge(str(k), str(i))
G.view()
结果:
备注:
- 当形状设置为 'plain'
时,节点获得 HTML 的形状
- 颜色渐变在单元格
<TD>
中指定为 BGCOLOR=“colour1:colour2”
- 渐变的角度也在单元格
<TD>
中指定,例如 GRADIENTANGLE=“45”
更多关于 HTML 节点的信息:http://graphviz.org/doc/info/shapes.html#gradientangle
我正在尝试设计一种具有特定颜色和形状的非常特定类型的图表,但我无法判断这是否可以通过 Graphviz 实现。
我的目标是绘制一个有向图,其中每个节点:
- 由 3 个水平排列的小方框组成(
striped
rectangle
或record
、rounded
) - 相应地包含 3
labels
- 填充渐变
- 有一个黑色方形节点位于中间框的顶部
示例(所有黑框都已手动放置):
我已经达到了第三个要求,但我正在努力执行最后一个要求。您如何将方形节点(rect
、square
、box
等)放置在第一组节点(彩色矩形)的顶部,以便它们完全适合中间框的尺寸他们是为了掩盖?使用 Graphviz 甚至可能吗?
示例代码 (Python):
from graphviz import Digraph
# Dictionary storing relations between nodes
d = {0: set([1, 2, 3]),
1: set([4, 5, 6]),
2: set([7, 8, 9, 10]),
3: set([0]),
4: set([]),
5: set([]),
6: set([]),
7: set([]),
8: set([0]),
9: set([]),
10: set([])}
# List of node labels (3 labels per node)
P = [('S', 'M', 'S'),
('M', 'S', 'L'),
('M', 'S', 'S'),
('M', 'S', 'M'),
('S', 'L', 'L'),
('S', 'L', 'M'),
('S', 'L', 'X'),
('S', 'S', 'S'),
('S', 'S', 'M'),
('S', 'S', 'L'),
('S', 'S', 'X')]
# Dictionary storing the colors corresponding to each label
c = {'S':'olivedrab1',
'M':'mediumturquoise',
'L':'deepskyblue',
'X':'palevioletred1'}
# Create a "directed graph" with general node and edge attributes
G = Digraph(node_attr={'shape':'record',
'style':'rounded, filled',
'color':'white',
'height':'0.1',
'fontcolor':'white'},
edge_attr={'color':'grey',
'arrowhead':'vee'}
)
G.attr('graph', bgcolor='transparent')
# 1st pass: create all nodes (0 to 10)
for k in d:
l1, l2, l3 = P[k]
# set specific attribute to each node (label & colors)
G.attr('node', label='{} | {} | {}'.format(l1, ' ', l2), fillcolor='{}:{}'.format(c[l1], c[l2]))
G.node(str(k))
# 2nd pass: create edges between nodes
for k in d:
l1, l2, l3 = P[k]
for i in d[k]:
if i in d:
G.edge(str(k), str(i))
# Then, how to overlap black square nodes ?
我认为在 dot/graphviz 中不可能强制节点将一个节点叠加到另一个节点上;我想这会打败视觉渲染图形的全部意义。
此代码对节点使用 HTML(-like)形状;这些描述了一个三单元格 table,左侧和右侧具有渐变颜色,中间为纯黑色和白色文本。
import graphviz
# Dictionary storing relations between nodes
d = {0: set([1, 2, 3]),
1: set([4, 5, 6]),
2: set([7, 8, 9, 10]),
3: set([0]),
4: set([]),
5: set([]),
6: set([]),
7: set([]),
8: set([0]),
9: set([]),
10: set([])}
# List of node labels (3 labels per node)
P = [('S', 'M', 'S'),
('M', 'S', 'L'),
('M', 'S', 'S'),
('M', 'S', 'M'),
('S', 'L', 'L'),
('S', 'L', 'M'),
('S', 'L', 'X'),
('S', 'S', 'S'),
('S', 'S', 'M'),
('S', 'S', 'L'),
('S', 'S', 'X')]
# Dictionary storing the colors corresponding to each label
c = {'S':'olivedrab1:grey',
'M':'mediumturquoise:gray',
'L':'deepskyblue:gray',
'X':'palevioletred1:gray'}
# Create a "directed graph" with general node and edge attributes
G = graphviz.Digraph(
format='svg'
,edge_attr={'color':'grey',
'arrowhead':'vee'}
)
G.attr('graph', bgcolor='transparent')
# 1st pass: create all nodes (0 to 10)
for k in d:
l1, l2, l3 = P[k]
G.node(name=str(k),shape='plain',label=f'''<
<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="gray">
<TR>
<TD BGCOLOR="{c[l1]}" GRADIENTANGLE="45">{l1}</TD>
<TD BGCOLOR="black"><FONT COLOR="white">{l2}</FONT></TD>
<TD BGCOLOR="{c[l3]}" GRADIENTANGLE="135">{l3}</TD>
</TR>
</TABLE>
>
'''
)
# 2nd pass: create edges between nodes
for k in d:
l1, l2, l3 = P[k]
for i in d[k]:
if i in d:
G.edge(str(k), str(i))
G.view()
结果:
备注:
- 当形状设置为 'plain' 时,节点获得 HTML 的形状
- 颜色渐变在单元格
<TD>
中指定为BGCOLOR=“colour1:colour2”
- 渐变的角度也在单元格
<TD>
中指定,例如GRADIENTANGLE=“45”
更多关于 HTML 节点的信息:http://graphviz.org/doc/info/shapes.html#gradientangle