如何使用Graphviz将节点放置在其他节点之上?

How to place nodes on top of others with Graphviz?(如何使用Graphviz将节点放置在其他节点之上?)
本文介绍了如何使用Graphviz将节点放置在其他节点之上?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试设计一种具有某些颜色和形状的特定类型的图形,但我无法确定使用Graphviz是否可以实现这一点。

我的目标是画一个有向图,其中每个节点:

  • 由水平对齐的3个较小的框组成(stripedrectanglerecordrounded)
  • 相应包含3个labels
  • 用渐变填充
  • 中间框顶部有一个黑色正方形节点

示例(所有黑盒均已手动放置):

我已经达到了第三个要求,但我正在努力实现最后一个要求。如何将正方形节点(rectsquarebox等)放置在第一组节点(彩色矩形)的顶部,以使它们与要覆盖的中间框的尺寸完全匹配?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 ?

推荐答案

我认为在点/图形中不可能强制节点将一个节点叠加到另一个节点上;我想这会有点儿违背可视化呈现图形的全部意义。

此代码对节点使用类似于HTML的形状;这些形状描述了一个由三个单元格组成的表格,表格的左侧和右侧为渐变颜色,中间为纯黑和白色文本。

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()

结果:

备注:

  • 当Shape设置为‘Play’时,该节点将获取HTML的形状
  • 颜色渐变在单元格<TD>中指定为BGCOLOR="colour1:colour2"
  • 在单元格<TD>中也指定了渐变角度,例如GRADIENTANGLE="45"

此处提供有关HTML节点的更多信息:http://graphviz.org/doc/info/shapes.html#gradientangle

这篇关于如何使用Graphviz将节点放置在其他节点之上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Leetcode 234: Palindrome LinkedList(Leetcode 234:回文链接列表)
How do I read an Excel file directly from Dropbox#39;s API using pandas.read_excel()?(如何使用PANDAS.READ_EXCEL()直接从Dropbox的API读取Excel文件?)
subprocess.Popen tries to write to nonexistent pipe(子进程。打开尝试写入不存在的管道)
I want to realize Popen-code from Windows to Linux:(我想实现从Windows到Linux的POpen-code:)
Reading stdout from a subprocess in real time(实时读取子进程中的标准输出)
How to call type safely on a random file in Python?(如何在Python中安全地调用随机文件上的类型?)