python graphviz 中的子图方法?

subgraph method in python graphviz?

所以我尝试在 python 上使用 graphviz 包,它有一个名为 subgraph() 的方法,但我认为它与网络理论中广泛使用的定义不同。

据我所知,子图是指节点和边是另一个图的子集的图。

在 graphviz 用户指南上说:
添加给定唯一图参数的当前内容作为子图或 return 上下文管理器 returning 使用给定(名称、评论等)参数创建的新图实例,其内容作为子图添加当离开上下文管理器的 with-block 时。

这是用户指南中的示例

import graphviz
p = Graph(name='parent')
p.edge('spam', 'eggs')
c = Graph(name='child', node_attr={'shape': 'box'})
c.edge('foo', 'bar')

p.subgraph(c)

根据网络理论,图p应具有所有节点'spam'、'eggs'、'foo'、'bar',子图c应由节点和边构成在图 p 中使用。

但事实并非如此。似乎 subgraph() 方法只是将两个图合二为一。我说得对吗?

什么是特殊的聚类子图? (如果子图的名称以 'cluster' 开头,布局引擎会将其视为特殊的簇子图)。我在 google 中找不到任何结果。

谢谢

您可以将 subgraph 视为对节点和边进行逻辑分组的工具。

考虑以下示例(如果您不介意,我将使用本机 Graphviz 语法,而不是 Python Graphviz 包装器):

digraph {
    a -> b
    c
    d -> e
    f
    g -> h
    c -> a
}

现在让我们在节点 cde 周围添加一个子图并更改全局节点属性,例如,给它们矩形和红色:

digraph {
    a -> b
    subgraph mysubgraph {
        node [shape=rect color=red]
        c
        d -> e
    }
    f
    g -> h
    c -> a
}

如您所见,节点放置没有任何变化,但子图中的那些节点改变了形状和颜色。另外,请注意你是对的:我们影响了 c 个节点,它被定义为一个节点,d;e 个节点,它们被隐式定义为一个边。

我们还可以通过 rank 属性使用子图来控制节点放置(这就是大多数时候使用的子图)。要强制子图中的节点出现在同一行上,请向子图中添加 rank=same 属性:

digraph {
    a -> b
    subgraph mysubgraph {
        node [shape=rect color=red]
        rank=same
        c
        d -> e
    }
    f
    g -> h
    c -> a
}

集群是一个完全不同的故事。当您在子图名称的开头添加单词 "cluster" 时,该集群内定义的节点将物理聚集在一起。您还将获得一个矩形(默认情况下)将这些节点包裹在您的图表上:

digraph {
    a -> b
    subgraph cluster_mysubgraph {
        node [shape=rect color=red]
        c
        d -> e
    }
    f
    g -> h
    c -> a
}

注意这张图和第二张图的区别。 我建议您谨慎使用集群。一旦在集群内外的节点之间建立了连接,就布局而言,事情可能会变得很奇怪。

顺便说一下,通过官方文档学习 garphviz 真的很难,因为它们更多的是参考而不是指南。但他们也有一个很好的指南,用普通人(对不起,数学家)的良好语言编写,但它被埋在 Graphviz 网站中:https://graphviz.gitlab.io/_pages/pdf/dotguide.pdf