图形可视化

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: 随机布局(2D 和 3D)

以下算法为一般图形生成美观的布局:

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

  • Graph.layout_drl: 用于大型图的DrL布局(2D和3D),一种可扩展的力导向布局

  • Graph.layout_fruchterman_reingold: Fruchterman-Reingold 布局(2D 和 3D),一种基于经典物理的“弹簧-电荷”布局

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

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

  • Graph.layout_lgl: 大型图布局

  • Graph.layout_mds: 多维缩放布局

  • Graph.layout_umap: 均匀流形逼近与投影(2D和3D)。当图由松散连接的“簇”组成时,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笔记本中使用此功能,请参见下文)。这背后使用了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) 如果请求了聚类外壳,则有一个艺术家;(ii) 一个艺术家用于边;(iii) 一个艺术家用于顶点;(iv) 一个艺术家用于每个边标签;(v) 一个艺术家用于每个顶点标签。

要将 matplotlib_ 设置为默认的绘图后端,您可以设置:

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

那么你就不需要再指定一个Axes了:

>>> ig.plot(g)

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

在Jupyter笔记本中绘制图形

igraph 支持通过 Cairomatplotlib 后端在 Jupyter 笔记本中内嵌绘图。如果你在没有 matplotlib 轴的情况下从笔记本单元格调用 igraph.plot,图像将显示在相应的输出单元格中。使用 bbox 参数来缩放图像,同时保持顶点、文本和其他元素的大小。例如,要获得一个紧凑的绘图(仅使用 Cairo 后端):

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

这些内嵌图表可以是PNG或SVG格式。目前有一个未解决的错误,如果在同一个笔记本中绘制多个图表,SVG格式会失败:我们正在努力修复这个问题。在此期间,您可以使用PNG格式。

如果你想在Jupyter笔记本中使用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对象(networkx, graph-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'],
...         )

请参阅教程以获取示例和完整的选项列表。