图形可视化
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)
将图保存到文件
调用 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)
然后,您可以通过 ax 和 fig 变量(或您给它们命名的任何名称)随意进一步操作轴和图形。此变体不直接使用 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 中的 Cairo 和 matplotlib 后端进行内联绘图。如果您从 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 格式)以及转换为流行的图形库,例如 networkx 和 graph-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'],
... )
有关示例和选项的完整列表,请参见教程。