[英]pydot: is it possible to plot two different nodes with the same string in them?
I'm using pydot in order to draw graphs in python. 我正在使用pydot在python中绘制图形。 I'd like to represent a decision tree, say something like (a1,a2,a3 are attributes and two classes are 0 and 1:
我想代表一个决策树,比如说(a1,a2,a3是属性,两个类是0和1:
a1>3
/ \
a2>10 a3>-7
/ \ / \
1 0 1 0
However, using pydot, only two leaves are created and the tree looks like this (png attached): 但是,使用pydot,只创建了两个叶子,树看起来像这样(png附加):
a1>3
/ \
a2>10 a3>-7
| X |
1 0
Now, in this simple case the logic is fine but in larger trees it is messy internal nodes belonging to different branches are unified. 现在,在这个简单的情况下,逻辑很好,但在较大的树中,属于不同分支的凌乱的内部节点是统一的。
The simple code I'm using is: 我正在使用的简单代码是:
import pydot
graph = pydot.Dot(graph_type='graph')
edge = pydot.Edge("a_1>3", "a_2>10")
graph.add_edge(edge)
edge = pydot.Edge("a_1>3", "a_3>-7")
graph.add_edge(edge)
edge = pydot.Edge("a_2>10", "1")
graph.add_edge(edge)
edge = pydot.Edge("a_2>10", "0")
graph.add_edge(edge)
edge = pydot.Edge("a_3>-7", "1")
graph.add_edge(edge)
edge = pydot.Edge("a_3>-7", "0")
graph.add_edge(edge)
graph.write_png('simpleTree.png')
I also tried creating different node objects than create the edges and than add it to the graph but it seems that pydot checks the node pool for nodes with the same name instead of creating a new one. 我还尝试创建不同的节点对象而不是创建边缘,而不是将其添加到图形中,但似乎pydot会检查节点池中是否有相同名称的节点而不是创建新节点。
Any ideas? 有任何想法吗? thanks!
谢谢!
Your nodes always need a unique names, otherwise you cannot name them uniquely to attach edges between them. 您的节点始终需要唯一的名称,否则您无法将它们唯一地命名为在它们之间附加边。 However, you can give each node a label, which is what is displayed when rendered.
但是,您可以为每个节点提供一个标签,这是呈现时显示的标签。
So you'll need to add nodes with unique ids: 因此,您需要添加具有唯一ID的节点:
graph = pydot.Dot(graph_type='graph')
graph.add_node(pydot.Node('literal_0_0', label='0'))
graph.add_node(pydot.Node('literal_0_1', label='0'))
graph.add_node(pydot.Node('literal_1_0', label='1'))
graph.add_node(pydot.Node('literal_1_1', label='1'))
then add graph edges connecting those nodes: 然后添加连接这些节点的图形边缘:
edge = pydot.Edge("a_2>10", "literal_0_0")
graph.add_edge(edge)
edge = pydot.Edge("a_2>10", "literal_1_0")
graph.add_edge(edge)
edge = pydot.Edge("a_3>-7", "literal_0_1")
graph.add_edge(edge)
edge = pydot.Edge("a_3>-7", "literal_1_1")
graph.add_edge(edge)
Together with the rest of the edges you defined this makes: 与您定义的其余边缘一起使得:
The "canonical" answer is to use the uuid
module from the standard library, as networkx
does here . “规范”的答案是使用标准库中的
uuid
模块,就像networkx
在这里一样 。
This is better than using id
to create node names for pydot
that correspond to the nodes in your original graph, because if (in theory) a node object gets deleted while you are building your pydot
graph, then that id
won't necessarily be unique. 这比使用
id
为pydot
创建与原始图中的节点对应的节点名更好,因为如果(理论上)在构建pydot
图时删除了节点对象,那么该id
不一定是唯一的。 In contrast, the UUID
objects created are unique, persistent and independent of the lifespan of the original nodes. 相反,创建的
UUID
对象是唯一的,持久的并且独立于原始节点的生命周期。
However for this to happen, something very weird must be going on while you create the pydot
graph, which is rather unlikely. 然而,为了实现这一点,在创建
pydot
图时必须进行一些非常奇怪的pydot
,这是不太可能的。 The advantage of using id
is that you don't need to build and pass around a mapping from original nodes to UUID
objects (so that you construct consistently the edges after adding the nodes). 使用
id
的优点是您不需要构建并传递从原始节点到UUID
对象的映射(以便在添加节点后一致地构造边)。
One interesting case are nested graphs: two different graphs may contain the same hashable object in networkx
(say a
), then id
cannot be used any more directly on the node. 一个有趣的例子是嵌套图:两个不同的图可能在
networkx
包含相同的可networkx
对象(比如说a
),那么id
不能再在节点上直接使用了。 But in that case, id
can still be used, by combining the (node, graph) pair as: str(id(node)) + str(id(graph))
. 但在这种情况下,仍然可以使用
id
,通过将(节点,图形)对组合为: str(id(node)) + str(id(graph))
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.