简体   繁体   English

使用 graphviz 更改特定节点形状 python

[英]Change specific node shape with graphviz python

I am currently trying to generate a graph, but I have one condition on that graph and that is that nodes with only outgoing arrows should be ellipses, the rest should have a box shape, this is what I have:我目前正在尝试生成一个图表,但我在该图表上有一个条件,那就是只有向外箭头的节点应该是椭圆,rest 应该有一个盒子形状,这就是我所拥有的:

这是图像ter插图,但每次运行都会产生其他东西

So in this case I want: 'Place Order-Importance shift-I-Obiect Typc--Customers' and 'Place Order--Quantity shift-1--Object Type--Orders' to be ellipses.因此,在这种情况下,我希望:“下订单-重要性转移-I-对象类型-客户”和“下订单-数量转移-1-对象类型-订单”为省略号。 The rest should be boxes. rest 应该是盒子。

I have tried multiple things including creating a list of specific nodes that should be that an ellipse shape, however it seems that one of the shape commands might be overruling an other one.我已经尝试了多种方法,包括创建一个应该是椭圆形的特定节点列表,但似乎其中一个形状命令可能会否决另一个。 Does anyone know how I can have my desired output?有谁知道我怎样才能得到我想要的 output?

Some info about the code:有关代码的一些信息:

I make a list called differences with the nodes that should have an ellips shape, the rest should be box shape.我制作了一个名为 differences 的列表,节点应该具有椭圆形,rest 应该是盒子形状。

The model object is an object that contains all the edges but comes from another previously build code which I would rather not change since I think it should be possible to it here. model object 是一个 object,它包含所有边,但来自另一个以前构建的代码,我不想更改它,因为我认为它应该可以在这里实现。

An edge object of model contains a 'source' node and a 'target' node. model 的边 object 包含一个“源”节点和一个“目标”节点。

I hope this is clear enough.我希望这已经足够清楚了。

The specific code (snippet) is here:具体代码(片段)在这里:

from graphviz import Digraph

 g = Digraph('G', filename='./output/model_' + str(mi), format='png')
 # nxg = nx.DiGraph()
 g.graph_attr.update(rankdir='BT')

 g.attr('node', shape='box')
 sources= list()
 targets = list()
 PossibleModel.MAX_DEPTH = 3

 """Let us first see what the possible inputs are"""
 for edge in model.get_edges():
    sources.append(str(edge.source))
    targets.append(str(edge.target))
    
 difference = list(set(sources) - set(targets))
 print('difference',difference)

 for edge in model.get_edges():
   edge_contained = ''
     for rule in br_rules:
         if str(edge.source) in rule or str(edge.target) in rule:
            edge_contained += rule + '\n'
     if edge_contained == '':
        g.attr('edge', color='red')
        g.edge(str(edge.source), str(edge.target),label=str(edge.weight))
        if str(edge.source) in difference:
            g.attr('node',attrs=str(edge.source),shape='ellipse')
        else:
            g.attr('node',attrs=str(edge.source), shape='box')
        g.attr('node',attrs=str(edge.target))
        
     else:
        g.attr('edge', color='blue')
        #str(round(edge.correlation, 2)))
        g.edge(str(edge.source), str(edge.target), label=edge_contained)
        if str(edge.source) in difference:
            g.attr('node',attrs=str(edge.source),shape='ellipse')
        else:
            g.attr('node',attrs=str(edge.source), shape='box')
        g.attr('node',attrs=str(edge.target), shape='box')

The Dot file code is here:点文件代码在这里:

digraph G {
graph [rankdir=BT]
node [shape=box]
edge [color=red]
"Place Order--Quantity_shift-1--Object_Type--Orders" -> "Determine shipping method--Shipping Method_shift-1--Object_Type--Orders" [label=100]
node [attrs="Place Order--Quantity_shift-1--Object_Type--Orders" shape=ellipse]
node [attrs="Determine shipping method--Shipping Method_shift-1--Object_Type--Orders"]
edge [color=red]
"Place Order--Importance_shift-1--Object_Type--Customers" -> "Determine shipping method--Shipping Method_shift-1--Object_Type--Orders" [label=100]
node [attrs="Place Order--Importance_shift-1--Object_Type--Customers" shape=ellipse]
node [attrs="Determine shipping method--Shipping Method_shift-1--Object_Type--Orders"]
edge [color=red]
"Calculate Order Value--Order Value_shift-1--Object_Type--Orders" -> "Determine shipping method--Shipping Method_shift-1--Object_Type--Orders" [label=100]
node [attrs="Determine shipping method--Shipping Method_shift-1--Object_Type--Orders"]
edge [color=red]
"Place Order--Quantity_shift-1--Object_Type--Orders" -> "Calculate Order Value--Order Value_shift-1--Object_Type--Orders" [label=100]
node [attrs="Place Order--Quantity_shift-1--Object_Type--Orders" shape=ellipse]
node [attrs="Calculate Order Value--Order Value_shift-1--Object_Type--Orders"]}'

Here is a solution using the gvpr language ( http://www.graphviz.org/pdf/gvpr.1.pdf ).这是使用gvpr语言 ( http://www.graphviz.org/pdf/gvpr.1.pdf ) 的解决方案。 gvpr comes with the Graphviz package so it should already be present on your computer. gvpr随 Graphviz package 一起提供,因此它应该已经存在于您的计算机上。
As a one-liner:作为单线:
gvpr -c 'N{if ($.indegree==0)$.shape="ellipse";else $.shape="box";}' yourfile.gv
What it does:它能做什么:

  • for each node对于每个节点
    • if there are 0 incoming edges ( indegree ) - set shape to ellipse如果有 0 个传入边(入度)- 将形状设置为椭圆
    • else set shape to box否则将形状设置为

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM