图形可视化

igraph 包含可视化图形的功能。它主要包含两个部分:图形布局和图形绘制。

在以下示例中,我们假设 igraph 被导入为 ig,并且 Graph 对象已事先创建,例如:

>>> import igraph as ig
>>> g = ig.Graph(edges=[[0, 1], [2, 3]])

有关每个函数和类的详细信息,请阅读API 参考。有关示例,请参见教程示例画廊

图形布局

图形布局是图的低维(通常为二维)表示。可以为同一个图计算不同的布局,它们通常会保留或突出图本身的独特属性。某些布局仅对特定类型的图有意义,例如树。

igraph 提供了多种图形布局。计算图形布局的通用函数是 Graph.layout()

>>> layout = g.layout(layout='auto')

支持的布局列表见下文。结果对象是 igraph.layout.Layout 的实例,并具有一些有用的属性

  • Layout.coords: 布局中顶点的坐标(每行是一个顶点)

  • Layout.dim: 嵌入的维数(通常为 2)

以及方法

  • Layout.boundaries() 包含布局极端坐标的矩形

  • Layout.bounding_box() 边界,但作为 igraph.drawing.utils.BoundingBox (见下文)

  • Layout.centroid() 图形布局质心的坐标

可以执行索引和切片,并返回所请求顶点的坐标

>>> coords_subgraph = layout[:2]  # Coordinates of the first two vertices

注意

返回的对象是包含坐标的列表的列表,而不是 igraph.layout.Layout 对象。您可以轻松地将结果包装到此类对象中

>>> layout_subgraph = ig.Layout(coords=layout[:2])

可以对布局执行线性变换

  • Layout.translate()

  • Layout.center()

  • Layout.scale()

  • Layout.fit_into()

  • Layout.rotate()

  • Layout.mirror()

以及通过以下方式进行通用非线性变换

  • Layout.transform()

支持以下常规布局

  • Graph.layout_star: 星形布局

  • Graph.layout_circle: 圆形/球形布局

  • Graph.layout_grid: 二维常规网格布局

  • Graph.layout_grid_3d: 三维常规网格布局

  • Graph.layout_random: 随机布局(二维和三维)

以下算法为通用图形生成美观的布局

  • Graph.layout_davidson_harel: Davidson-Harel 布局,基于模拟退火优化,包括边交叉

  • Graph.layout_drl: 大型图的 DrL 布局(二维和三维),一种可伸缩的力导向布局

  • Graph.layout_fruchterman_reingold: Fruchterman-Reingold 布局(二维和三维),一种基于经典物理的“弹簧-电力”布局

  • Graph.layout_graphopt: graphopt 算法,另一种力导向布局

  • Graph.layout_kamada_kawai: Kamada-Kawai 布局(二维和三维),一种基于经典物理的“弹簧”布局

  • Graph.layout_lgl: 大型图布局

  • Graph.layout_mds: 多维尺度布局

  • Graph.layout_umap: 均匀流形近似与投影(二维和三维)。当图由彼此松散连接的“簇”组成时,UMAP 的效果特别好。

以下算法适用于(以及 Sugiyama 有向无环图DAG

  • Graph.layout_reingold_tilford: Reingold-Tilford 布局

  • Graph.layout_reingold_tilford_circular: 环形 Reingold-Tilford 布局

  • Graph.layout_sugiyama: Sugiyama 布局,一种分层布局

对于二分图,有一个专用函数

  • Graph.layout_bipartite: 二分布局

将来可能会根据需求添加更多功能。

图形绘制

一旦计算出图形布局,igraph 就可以辅助绘制。绘制通过单个函数 igraph.plot 进行。

使用默认图像查看器绘制

直接调用 igraph.plot 会生成一个临时文件并使用默认图像查看器打开它

>>> ig.plot(g)

(如果您在 Jupyter notebook 中使用,请参见下文)。这在后台使用了 Cairo 库。

将图保存到文件

调用 igraph.plot 并带有 target 参数时,会将图形图像存储在指定文件中,但不会自动打开。根据文件名扩展名,可以选择以下任何输出格式:PNG、PDF、SVG 和 PostScript

>>> ig.plot(g, target='myfile.pdf')

注意

PNG 是一种栅格图像格式,而 PDF、SVG 和 PostScript 是矢量图像格式。如果您打算使用 Inkscape 或 Illustrator 等矢量图像编辑器对图像进行精修,请选择后三种格式之一。

在 Matplotlib 图中绘制图形

如果目标参数是 matplotlib 轴,则图将绘制在该轴内

>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> ig.plot(g, target=ax)

然后,您可以通过 axfig 变量(或您给它们命名的任何名称)随意进一步操作轴和图形。此变体不直接使用 Cairo,并且可能缺少 Cairo 后端中可用的一些功能:请在 Github 上提出问题以请求特定功能。

注意

绘制有根树时,Cairo 会自动将根放在图像顶部,叶子放在底部。对于 matplotlib,根通常在底部。您可以通过调用 ax.invert_yaxis() 轻松地将根放在顶部。

通过 matplotlib 绘制可以轻松地将 igraph 与其他图结合起来。例如,如果您想创建一个带有两个面板的图,显示数据集的不同方面,例如图形和条形图,您可以轻松实现。

>>> import matplotlib.pyplot as plt
>>> fig, axs = plt.subplots(1, 2, figsize=(8, 4))
>>> ig.plot(g, target=axs[0])
>>> axs[1].bar(x=[0, 1, 2], height=[1, 5, 3], color='tomato')

另一种常见情况是事后修改图形绘制,以实现某种自定义。例如,您可能希望更改顶点的大小和颜色

>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> ig.plot(g, target=ax)
>>> artist = ax.get_children()[0] # This is a GraphArtist
>>> dots = artist.get_vertices()
>>> dot.set_facecolors(['tomato'] * g.vcount())
>>> dot.set_sizes(dot.get_sizes() * 2) # double the default radius

如果您无法弄清楚如何使用下面的绘图选项,这也可以作为一种变通方法:只需使用默认设置,然后通过标准 matplotlib 工具自定义图形的外观。

注意

artist.get_children() 的顺序如下:(i) 如果请求,一个用于聚类凸包的 artist;(ii) 一个用于边的 artist;(iii) 一个用于顶点的 artist;(iv) 一个用于每个边标签的 artist;(v) 一个用于每个顶点标签的 artist。

要将 matplotlib_ 用作默认绘图后端,您可以设置

>>> ig.config['plotting.backend'] = 'matplotlib'

那么您就不必再指定 Axes

>>> ig.plot(g)

将自动为您创建一个新的 Axes 并返回它。

在 Jupyter Notebook 中绘制图形

igraph 支持通过 Jupyter notebook 中的 Cairomatplotlib 后端进行内联绘图。如果您从 notebook 单元格中调用 igraph.plot 而没有 matplotlib 轴,图像将以内联方式显示在相应的输出单元格中。使用 bbox 参数缩放图像,同时保留顶点、文本和其他 artist 的大小。例如,要获得紧凑的绘图(仅使用 Cairo 后端)

>>> ig.plot(g, bbox=(0, 0, 100, 100))

这些内联图可以是 PNG 或 SVG 格式。目前有一个未解决的错误,导致每个 notebook 绘制多个图时 SVG 会失败:我们正在努力修复此问题。在此期间,您可以使用 PNG 表示。

如果您想在 Jupyter notebook 中使用 matplotlib 引擎,可以使用上述方法。首先创建一个轴,然后通过 target 参数告知 igraph.plot

>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> ig.plot(g, target=ax)

导出为其他图形格式

如果 igraph 缺少某个绘图功能,而您又等不及我们将其包含进来,您始终可以将图形导出为多种格式并使用外部图形绘图工具。我们支持转换为文件(例如 graphviz 使用的 DOT 格式)以及转换为流行的图形库,例如 networkxgraph-tool

>>> dot = g.write('/myfolder/myfile.dot')
>>> n = g.to_networkx()
>>> gt = g.to_graph_tool()

如果导出到文件,则不需要安装任何库,但如果直接转换为外部 Python 对象(networkxgraph-tool),则需要这些库。

绘图选项

您可以向 plot 函数添加一个参数 layout 来指定预计算的布局,例如:

>>> layout = g.layout("kamada_kawai")
>>> ig.plot(g, layout=layout)

也可以直接使用布局算法的名称

>>> ig.plot(g, layout="kamada_kawai")

如果未指定布局,igraph 将使用专用函数 layout_auto(),它会根据顶点和边的数量在几种可能的布局中选择一种。

您还可以通过附加参数指定顶点和边的颜色、大小和标签等,例如:

>>> ig.plot(g,
...         vertex_size=20,
...         vertex_color=['blue', 'red', 'green', 'yellow'],
...         vertex_label=['first', 'second', 'third', 'fourth'],
...         edge_width=[1, 4],
...         edge_color=['black', 'grey'],
...         )

有关示例和选项的完整列表,请参见教程