pydot:是不是可以绘制两个具有相同字符串的不同节点?

Posted

技术标签:

【中文标题】pydot:是不是可以绘制两个具有相同字符串的不同节点?【英文标题】:pydot: is it possible to plot two different nodes with the same string in them?pydot:是否可以绘制两个具有相同字符串的不同节点? 【发布时间】:2012-10-12 07:59:35 【问题描述】:

我正在使用 pydot 在 python 中绘制图形。 我想代表一个决策树,比如(a1,a2,a3 是属性,两个类是 0 和 1:

       a1>3
      /    \
  a2>10    a3>-7
   /  \     /  \
  1    0   1    0

但是,使用 pydot,只创建了两片叶子,树看起来像这样(附上 png):

       a1>3
      /    \
  a2>10    a3>-7
      |  X  |
      1     0

现在,在这种简单的情况下,逻辑很好,但在较大的树中,属于不同分支的混乱内部节点是统一的。

我使用的简单代码是:

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

我还尝试创建不同的节点对象而不是创建边并将其添加到图中,但似乎 pydot 会检查节点池中是否具有相同名称的节点,而不是创建新节点。

有什么想法吗?谢谢!

【问题讨论】:

【参考方案1】:

“规范”的答案是使用标准库中的uuid 模块,如networkx does here。

这比使用idpydot 创建与原始图中的节点相对应的节点名称要好,因为如果(理论上)在构建pydot 图形时删除了一个节点对象,那么id 不一定是唯一的。相比之下,创建的UUID 对象是唯一的、持久的并且独立于原始节点的生命周期。

但是,要发生这种情况,在您创建 pydot 图表时一定会发生一些非常奇怪的事情,这不太可能发生。使用id 的优点是您不需要构建和传递从原始节点到UUID 对象的映射(这样您就可以在添加节点后始终如一地构造边)。

一个有趣的例子是嵌套图:两个不同的图可能在networkx(比如a)中包含相同的可散列对象,然后id不能再直接在节点上使用。但在这种情况下,id 仍然可以使用,只需将 (node, graph) 对组合为:str(id(node)) + str(id(graph))

【讨论】:

【参考方案2】:

您的节点总是需要一个唯一的名称,否则您不能唯一地命名它们以在它们之间附加边。但是,您可以给每个节点一个标签,这是渲染时显示的内容。

因此您需要添加具有唯一 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'))

然后添加连接这些节点的图边:

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)

连同您定义的其余边,这使得:

【讨论】:

以上是关于pydot:是不是可以绘制两个具有相同字符串的不同节点?的主要内容,如果未能解决你的问题,请参考以下文章

在相同的绘图空间上绘制两个 Seaborn sns.kdeplot 图形,但每个图形都有一个具有相同范围的不同颜色条

在ggplot2中绘制两个具有相同y变量但不同x变量的箱线图

如果它们位于不同的文件夹中,是不是可以有两个具有相同名称的类?

使用不同编码编码的两个不同字符串可以具有相同的字节序列吗?

是否可以创建一个函数而不是两个具有相同目的但参数类型不同的函数? (我可以删除重复的代码吗?)[重复]

ggplot2:绘制具有不同截距但具有相同斜率的回归线