Python NetworkX 图论建模可视化:从非赋权、赋权到有向图绘制全攻略

📅 发布时间:2026/8/27 4:19:01
Python NetworkX 图论建模可视化:从非赋权、赋权到有向图绘制全攻略 1. 从零开始为什么用Python画图是建模的“第一公里”搞数学建模或者数据分析的朋友肯定都遇到过这个场景拿到一堆数据脑子里构思了一个用图论模型来描述的方案比如社交网络分析、交通流模拟、知识图谱构建。方案的核心逻辑理清了但怎么把它直观地、有说服力地展示出来尤其是给那些不太懂技术的评委或同事看这时候一张清晰、专业的图Graph往往比千言万语都管用。很多人卡在了这“第一公里”——知道该用图但不知道如何快速、准确地把图画出来。我见过不少队伍模型建得天花乱坠论文里却用着从Visio或者PPT里拖出来的、连线歪歪扭扭、节点大小不一的示意图专业感瞬间掉了一半。更麻烦的是当需要基于图的结构进行计算比如最短路径、中心性分析时这些绘图工具就完全无能为力了。Python特别是借助networkx这个库完美地解决了这个问题。它让你能够“以代码定义图以代码分析图最后再用代码画出图”整个过程可复现、可调整、自动化程度高。简单来说networkx是一个用于创建、操作和研究复杂网络结构、动力学和功能的Python包。它内置了数十种经典图的生成算法、丰富的图论算法路径、连通性、匹配、流等以及多种布局和绘图功能。我们今天要解决的核心问题就是如何利用它针对三种最常见的图类型——非赋权图、赋权图、有向图——画出既美观又信息量充足的示意图。这不仅仅是“画图”更是将你的数学模型进行第一次可视化验证和沟通的关键步骤。2. 环境奠基安装networkx与理解绘图核心依赖在动手画任何图之前一个稳定、兼容的环境是基石。很多人尤其是初学者容易在这里踩坑。最常见的问题不是networkx本身而是它的绘图后端。2.1 安装networkx与matplotlib安装本身非常简单一条命令即可。我强烈建议使用虚拟环境来管理项目依赖避免不同项目间的包版本冲突。# 使用pip安装这是最通用的方式 pip install networkx matplotlib # 如果你使用Anaconda也可以用conda安装它会自动处理一些底层依赖 conda install networkx matplotlib这里的关键是matplotlib。networkx的绘图功能主要依赖于matplotlib作为渲染引擎。你可以把networkx想象成设计师它负责设计图的布局、节点和边的样式而matplotlib则是印刷厂负责把设计稿实际打印渲染出来。没有matplotlibnetworkx的绘图函数就无法工作。2.2 理解绘图后端与常见“画不出来”的问题安装好后一个经典的错误是运行绘图代码后弹出一个空白窗口或者什么都不显示。这通常不是代码逻辑错误而是matplotlib的交互模式或后端设置问题。对于脚本执行环境如.py文件或Jupyter Notebook之外的命令行默认情况下matplotlib的图形窗口在绘制完成后会立即关闭。为了让图像显示并停留你需要显式地调用plt.show()。这是最基本但最容易被遗忘的一步。import networkx as nx import matplotlib.pyplot as plt # 创建一个简单的图并绘制 G nx.Graph() G.add_edges_from([(1, 2), (2, 3), (3, 1)]) nx.draw(G, with_labelsTrue) plt.show() # 必须要有这一行图像才会显示并阻塞程序直到你关闭窗口对于Jupyter Notebook/Lab环境为了让图形内嵌在Notebook单元格中显示你需要在开头使用一个“魔术命令”来设置matplotlib的内联后端。%matplotlib inline import networkx as nx import matplotlib.pyplot as plt # 之后你的绘图代码图像会自动显示在单元格下方 G nx.Graph([(1, 2), (2, 3)]) nx.draw(G, with_labelsTrue) # 在Notebook中通常不需要显式调用 plt.show()注意如果你在Jupyter中使用了%matplotlib inline但图仍然不显示或者显示异常如图形错位、元素重叠可以尝试改用%matplotlib notebook。这个命令会提供一些交互功能如缩放、平移但在某些复杂布局下可能更稳定。如果问题依旧检查一下matplotlib的版本是否过旧或者尝试重启Notebook内核。后端选择在极少数情况下如果你的环境没有图形界面比如在某些服务器或Docker容器中你需要将matplotlib的后端设置为“无头”模式例如Agg然后将图保存为文件。import matplotlib matplotlib.use(Agg) # 在导入plt之前设置 import matplotlib.pyplot as plt import networkx as nx G nx.complete_graph(5) nx.draw(G) plt.savefig(my_graph.png) # 保存到文件 print(图形已保存为 my_graph.png)确保环境配置正确我们就有了挥洒创意的画布。接下来我们从最简单的图开始画起。3. 绘制非赋权图基础中的基础布局定乾坤非赋权图也叫无权图是图论中最基础的模型。它的边只表示节点间“是否存在连接”而不关心连接的“强度”或“成本”。社交网络中的“是否为好友”、电路板上的“是否连通”都可以用非赋权图表示。绘制这类图核心挑战不在于数据本身而在于如何通过布局算法让图的结构一目了然。3.1 创建图对象与添加元素networkx提供了几种图类最常用的是nx.Graph()无向图和nx.DiGraph()有向图下一节细说。创建和添加元素非常直观。import networkx as nx import matplotlib.pyplot as plt # 方法1逐步添加 G nx.Graph() # 创建一个空的无向图 G.add_node(1) # 添加单个节点节点可以是数字、字符串甚至对象 G.add_nodes_from([2, 3, 4]) # 从列表批量添加节点 G.add_edge(1, 2) # 在节点1和2之间添加一条边 G.add_edges_from([(2, 3), (3, 4), (4, 1)]) # 批量添加边 # 方法2在创建时直接初始化更简洁 G nx.Graph([(1, 2), (2, 3), (3, 4), (4, 1)]) # 边列表会自动创建涉及的节点3.2 核心绘图函数nx.draw与基础美化nx.draw()是最基础的绘图函数它接受图对象G和一系列参数来控制外观。# 基础绘图 nx.draw(G) plt.show()这行代码会生成一张图但很可能杂乱无章因为节点被随机放置。为了让图有意义我们必须引入布局算法。# 使用spring布局力导向布局并添加标签 pos nx.spring_layout(G, seed42) # seed参数确保每次运行布局一致便于调试 nx.draw(G, pos, with_labelsTrue, node_colorlightblue, node_size500, font_size10) plt.title(基础非赋权图示例) plt.show()pos: 一个字典键是节点值是节点的(x, y)坐标。spring_layout模拟了物理中的弹簧模型连接的边像弹簧未连接的节点互相排斥经过迭代后达到一个能量较低的平衡状态通常能产生比较清晰的布局。seed参数固定随机数种子保证可复现性。with_labelsTrue: 在节点上显示其标签即节点标识符。node_color和node_size: 控制节点的颜色和大小。font_size: 控制标签字体大小。3.3 深入理解布局算法如何让图“自己会说话”选择正确的布局算法是让非赋权图传达信息的关键。networkx提供了多种布局适用于不同结构的图。1. 环形布局 (circular_layout)适用于展示循环结构或强调所有节点地位平等。pos nx.circular_layout(G) nx.draw(G, pos, with_labelsTrue, node_colorlightgreen) plt.show()2. 随机布局 (random_layout)节点完全随机放置。除非用于测试或艺术效果否则不推荐因为无法反映任何结构信息。pos nx.random_layout(G)3. 谱布局 (spectral_layout)利用图的拉普拉斯矩阵的特征向量来定位节点。对于某些具有明显社区结构的图效果非常好能将同一社区的节点聚集在一起。pos nx.spectral_layout(G)4. 壳层布局 (shell_layout)将节点放置在一系列同心圆上。特别适合展示具有层次结构或核心-边缘结构的网络比如某些社交网络核心人物在内圈普通用户在外圈。# 假设我们有一个核心节点集 [1, 2] 和外圈节点集 [3, 4, 5, 6] G nx.complete_graph(6) # 创建一个6个节点的完全图举例 core_nodes [1, 2] other_nodes [n for n in G.nodes() if n not in core_nodes] pos nx.shell_layout(G, nlist[core_nodes, other_nodes]) nx.draw(G, pos, with_labelsTrue) plt.show()实战心得布局选择与调参中小型图100节点spring_layout是默认且最通用的选择。你可以通过k参数调整节点间的理想距离默认值约为1/sqrt(n)iterations参数调整迭代次数默认50。对于复杂图增加迭代次数如iterations200可能得到更稳定的布局。层次清晰的图优先尝试shell_layout或spectral_layout。大型图1000节点spring_layout会非常慢。考虑使用nx.draw_networkx_nodes和nx.draw_networkx_edges分别绘制并可能需要对节点进行采样或使用专门的大图布局工具如graph-tool或Gephi导出布局后再用networkx画。固定布局如果你有一组预设的节点坐标比如地图上的城市可以直接构建pos字典传入draw函数。绘制非赋权图是基本功核心在于通过布局揭示结构。当图上需要承载更多信息比如边的权重时我们就进入了赋权图的领域。4. 绘制赋权图让边的“分量”可视化赋权图也叫加权图它的每条边都有一个数值权重可以代表距离、成本、流量、相似度等。在数学建模中赋权图无处不在如交通网络权重为距离或时间、通信网络权重为带宽或延迟。绘制赋权图的关键是如何将边的权重这个“隐形”信息通过视觉元素如边的粗细、颜色、标签有效地呈现出来。4.1 为边添加权重属性在networkx中权重是作为边的一个属性来存储的。import networkx as nx # 创建一个赋权图无向 G nx.Graph() # 添加带权重的边。权重属性名通常约定俗成叫 weight G.add_edge(A, B, weight4) G.add_edge(B, C, weight2) G.add_edge(A, C, weight5) G.add_edge(C, D, weight1) G.add_edge(B, D, weight7) # 也可以批量添加 # edges_with_weight [(A,B,4), (B,C,2), ...] # G.add_weighted_edges_from(edges_with_weight)4.2 基于权重控制边的视觉通道视觉编码是信息可视化的核心。对于权重我们主要有三种编码方式粗细、颜色和标签。通常组合使用以达到最佳效果。1. 用边的粗细表示权重这是最直观的方式之一。权重越大边越粗。import matplotlib.pyplot as plt pos nx.spring_layout(G, seed42) # 提取所有权重用于后续归一化 weights nx.get_edge_attributes(G, weight).values() # 将权重列表转换为一个与边顺序对应的列表 weight_list [G[u][v][weight] for u, v in G.edges()] # 绘制节点和标签 nx.draw_networkx_nodes(G, pos, node_colorlightblue, node_size500) nx.draw_networkx_labels(G, pos) # 关键绘制边线宽与权重成正比 # 这里对权重进行缩放避免线宽过大或过小。因子2.0可以调整。 nx.draw_networkx_edges(G, pos, width[w * 2.0 for w in weight_list]) plt.title(赋权图 - 边粗表示权重) plt.axis(off) # 关闭坐标轴 plt.show()这里我们使用了draw_networkx_nodes,draw_networkx_edges,draw_networkx_labels这三个函数来分别绘制图的不同部分从而获得更精细的控制。width参数接受一个标量或一个与边列表顺序对应的宽度列表。2. 用边的颜色表示权重颜色可以表示权重的大小通过颜色深浅/冷暖或类别通过不同色相。这里我们用颜色深浅colormap来表示连续权重。import matplotlib.cm as cm pos nx.spring_layout(G, seed42) weights nx.get_edge_attributes(G, weight) weight_list [weights[(u, v)] for u, v in G.edges()] # 选择一个颜色映射如 viridis (深到浅)plasma, YlOrRd (黄橙红) cmap cm.get_cmap(YlOrRd) # 将权重归一化到 [0, 1] 区间用于映射颜色 norm_weights [(w - min(weight_list)) / (max(weight_list) - min(weight_list)) for w in weight_list] edge_colors [cmap(w) for w in norm_weights] # 得到RGBA颜色列表 nx.draw_networkx_nodes(G, pos, node_colorlightgray, node_size500) nx.draw_networkx_labels(G, pos) # 用颜色列表绘制边 nx.draw_networkx_edges(G, pos, edge_coloredge_colors, width2) plt.title(赋权图 - 边色表示权重 (YlOrRd)) plt.axis(off) plt.show()3. 为边添加权重标签最精确的方式直接将权重数字标在边上。pos nx.spring_layout(G, seed42) nx.draw(G, pos, with_labelsTrue, node_colorw, edge_colorgray, width2, font_weightbold) # 单独绘制边的权重标签 edge_labels nx.get_edge_attributes(G, weight) nx.draw_networkx_edge_labels(G, pos, edge_labelsedge_labels, font_colorred) plt.title(赋权图 - 标签显示权重) plt.axis(off) plt.show()draw_networkx_edge_labels函数专门用于在边旁边绘制标签。一个常见问题是标签位置可能不理想或与边重叠可以通过调整label_pos参数默认为0.5表示边的中点或font_size来改善。4.3 综合应用粗细、颜色、标签三合一在实际的建模报告或论文中为了达到最佳的沟通效果我们常常需要综合运用多种视觉编码。pos nx.spring_layout(G, seed42) weights nx.get_edge_attributes(G, weight) weight_list [weights[(u, v)] for u, v in G.edges()] # 1. 颜色和粗细都基于权重 cmap cm.get_cmap(Blues) norm_weights [(w - min(weight_list)) / (max(weight_list) - min(weight_list)) for w in weight_list] edge_colors [cmap(w) for w in norm_weights] # 线宽在基础值上根据权重增加 base_width 2 edge_widths [base_width w * 0.5 for w in weight_list] # 绘制 nx.draw_networkx_nodes(G, pos, node_colorlightyellow, node_size700, edgecolorsblack) nx.draw_networkx_labels(G, pos, font_size12, font_weightbold) nx.draw_networkx_edges(G, pos, edge_coloredge_colors, widthedge_widths) # 2. 添加权重标签使用一个对比色 edge_labels nx.get_edge_attributes(G, weight) nx.draw_networkx_edge_labels(G, pos, edge_labels, font_size9, font_colordarkred, bboxdict(facecolorwhite, edgecolornone, alpha0.7)) plt.title(综合可视化粗细、颜色、标签表示边权重) plt.axis(off) plt.tight_layout() # 自动调整子图参数使之填充整个图像区域。 plt.show()注意视觉编码并非越多越好。如果权重差异不大过度使用粗细和颜色可能造成视觉混乱此时仅使用标签可能是最清晰的选择。始终要考虑读者的认知负荷目标是“一目了然”而不是“炫技”。掌握了赋权图的画法你就能将模型中的量化关系直观呈现。接下来我们处理另一种常见且重要的图类型——有向图。5. 绘制有向图明确流动与依赖关系有向图Digraph的边具有方向从源节点u指向目标节点v。它用于建模具有明确方向性的关系如网页链接A链接到B、任务依赖A完成后B才能开始、资金流向等。绘制有向图的核心是如何清晰无误地表达出边的方向。5.1 创建有向图对象使用nx.DiGraph()来创建有向图其节点和边的添加方式与无向图类似。import networkx as nx # 创建有向图 DG nx.DiGraph() DG.add_edges_from([(1, 2), (2, 3), (3, 1), (3, 4), (4, 2)]) # 也可以添加带权重的有向边 # DG.add_weighted_edges_from([(1, 2, 0.5), (2, 3, 0.8)])5.2 使用箭头表达方向networkx的draw函数族通过arrow相关参数来控制箭头的绘制。最常用的是nx.draw_networkx_edges中的arrows,arrowstyle, 和arrowsize 参数。import matplotlib.pyplot as plt pos nx.spring_layout(DG, seed42) nx.draw_networkx_nodes(DG, pos, node_colorlightcoral, node_size500) nx.draw_networkx_labels(DG, pos) # 关键绘制带箭头的边 # arrowsTrue 是默认的但为了清晰我们显式写出 # arrowstyle- 指定箭头样式- 是简单的三角箭头 # arrowsize15 控制箭头的大小 nx.draw_networkx_edges(DG, pos, edge_colorgray, width2, arrowsTrue, arrowstyle-, arrowsize15) plt.title(基础有向图) plt.axis(off) plt.show()5.3 有向图布局的挑战与技巧有向图的布局比无向图更具挑战性因为布局算法需要同时考虑节点位置和边的指向以避免箭头交叉和指向不清。spring_layout虽然也能用但并非为有向图优化。networkx提供了一些专门用于有向图的布局或者我们可以通过一些技巧来改善。1. 分层布局 (multipartite_layout或自定义层级)对于具有明显层次或流程的有向图如工作流、依赖图分层布局是最清晰的。我们需要为每个节点指定一个“层”。# 假设我们有一个简单的AOV网Activity On Vertex DG nx.DiGraph() DG.add_edges_from([(需求, 设计), (设计, 开发), (开发, 测试), (测试, 发布), (设计, 测试)]) # 一个快速路径 # 手动定义层级在实际中可能需要用拓扑排序算法自动计算 layers {需求: 0, 设计: 1, 开发: 2, 测试: 3, 发布: 4} # 使用 multipartite_layout它根据节点在 subset_key 属性中的值进行分层 for node, layer in layers.items(): DG.nodes[node][layer] layer pos nx.multipartite_layout(DG, subset_keylayer) nx.draw(DG, pos, with_labelsTrue, node_colorlightgreen, arrowsTrue) plt.title(分层布局有向图 (工作流示例)) plt.axis(off) plt.show()2. 改进的力导向布局对于没有明显层次的有向图可以尝试使用nx.spring_layout但通过调整参数使其更适合有向图。一个技巧是让边的“引力”不对称但这需要更底层的定制。一个更简单实用的方法是使用nx.kamada_kawai_layout它基于节点间的理想距离有时对有向图能产生不错的效果。pos nx.kamada_kawai_layout(DG) nx.draw(DG, pos, with_labelsTrue, node_colorlightblue, arrowsTrue, connectionstylearc3,rad0.1) # 使用弧形边减少交叉 plt.title(Kamada-Kawai 布局有向图) plt.axis(off) plt.show()这里connectionstylearc3,rad0.1将边画成轻微的弧线这在边比较密集时有助于减少视觉上的交叉让箭头方向更易追踪。3. 有向赋权图的综合绘制结合有向和赋权是建模中的高级需求例如带流量的管道网络、带消耗的生产线。# 创建一个有向赋权图 DG nx.DiGraph() DG.add_weighted_edges_from([(Src, A, 5), (Src, B, 3), (A, C, 2), (B, C, 4), (C, Dst, 6)]) pos nx.spring_layout(DG, seed42) weights nx.get_edge_attributes(DG, weight) weight_list [weights[(u, v)] for u, v in DG.edges()] # 绘制节点和标签 nx.draw_networkx_nodes(DG, pos, node_colorgold, node_size700) nx.draw_networkx_labels(DG, pos, font_size11, font_weightbold) # 绘制边宽度代表权重箭头代表方向 edge_widths [w * 0.8 for w in weight_list] nx.draw_networkx_edges(DG, pos, widthedge_widths, edge_colorsteelblue, arrowsTrue, arrowsize20, connectionstylearc3,rad0.1) # 添加权重标签 edge_labels nx.get_edge_attributes(DG, weight) nx.draw_networkx_edge_labels(DG, pos, edge_labels, font_size9) plt.title(有向赋权图 (流量/成本网络示例)) plt.axis(off) plt.tight_layout() plt.show()实操心得箭头与标签的清晰度箭头大小根据图的大小和边的密度动态调整arrowsize。图大边多箭头要调大如20-30图小边少可以调小如10-15。标签避让边的权重标签 (edge_labels) 很容易和箭头或节点重叠。可以尝试使用bbox参数给标签添加一个半透明的白色背景如bboxdict(facecolorwhite, edgecolornone, alpha0.7)。微调label_pos例如0.7让标签更靠近目标节点但这需要针对每条边单独设置比较繁琐。如果重叠严重考虑是否必须显示所有权重或者能否用颜色/粗细替代部分标签。循环自环networkx可以处理自环add_edge(1,1)但默认绘制可能不美观。对于有自环的图可能需要使用nx.draw_networkx_edges并配合connectionstyle进行更精细的控制。掌握了非赋权、赋权、有向这三种基本图的绘制你已经能应对数学建模中80%的可视化需求。但要想让你的图从“能用”变得“出色”还需要一些进阶的美学和实用技巧。6. 进阶技巧与实战排坑从“能画”到“画得好”当你掌握了基本画法后下一个层次是让图形不仅正确而且专业、美观、易于解读。这部分分享的是一些教科书里不常讲但在实际项目中至关重要的经验和技巧。6.1 节点与边的深度定制networkx的绘图函数高度可定制几乎所有视觉元素都可以按节点或边进行个性化设置。按节点属性着色/调整大小假设你的节点代表城市有一个‘人口’属性你想用节点大小来反映人口。import networkx as nx import matplotlib.pyplot as plt G nx.Graph() G.add_node(北京, population2154) # 单位万 G.add_node(上海, population2428) G.add_node(广州, population1881) G.add_node(深圳, population1768) G.add_edges_from([(北京,上海), (北京,广州), (上海,深圳), (广州,深圳)]) pos nx.spring_layout(G, seed42) # 提取节点属性 populations nx.get_node_attributes(G, population) # 将人口数据映射为节点大小这里进行缩放避免图形过大 node_sizes [populations[node] * 0.1 for node in G.nodes()] # 可以按其他属性着色这里简单用颜色区分 node_colors [red, blue, green, orange] nx.draw(G, pos, nodelistlist(G.nodes()), # 确保顺序一致 node_sizenode_sizes, node_colornode_colors, with_labelsTrue, font_size10, font_weightbold) plt.title(按节点属性定制 (节点大小代表人口)) plt.axis(off) plt.show()为不同类型的边使用不同样式例如在一个交通网络中用实线表示高速公路虚线表示国道。G nx.Graph() G.add_edges_from([(A,B), (A,C), (B,D), (C,D)]) # 假设边(A,B)和(C,D)是高速公路其他是国道 edge_style_map {(A,B): solid, (C,D): solid, (A,C): dashed, (B,D): dashed} pos nx.circular_layout(G) nx.draw_networkx_nodes(G, pos, node_colorlightgray) nx.draw_networkx_labels(G, pos) # 分别绘制不同样式的边 solid_edges [e for e, style in edge_style_map.items() if style solid] dashed_edges [e for e, style in edge_style_map.items() if style dashed] nx.draw_networkx_edges(G, pos, edgelistsolid_edges, width2, stylesolid) nx.draw_networkx_edges(G, pos, edgelistdashed_edges, width1.5, styledashed) plt.title(混合边样式) plt.axis(off) plt.show()6.2 处理大型图与性能优化当节点和边数量成百上千时直接使用nx.draw会非常缓慢且生成的图可能是一团无法辨认的“毛球”。这时需要策略调整。1. 简化绘制关闭非必要元素# 对于大型图关闭标签、调整节点和边的大小为固定小值 nx.draw(G, pos, with_labelsFalse, node_size20, edge_colorgray, width0.5)2. 使用更高效的布局算法对于超大图10000节点spring_layout基本不可用。可以考虑使用nx.random_layout快速得到一个随机布局虽然乱但快。使用nx.spiral_layout或nx.shell_layout这类计算简单的布局。使用专业的大规模图可视化工具如Gephi,Cytoscape计算好布局然后将节点坐标导出再用networkx读取并绘制。networkx可以读取Gephi的.gexf格式文件其中包含布局信息。# 假设已有从Gephi导出的节点坐标文件 ‘coords.json’ import json with open(coords.json, r) as f: pos json.load(f) # pos 现在是一个 {node_id: [x, y]} 的字典可以直接用于nx.draw3. 采样或聚合如果图太大考虑是否真的需要可视化全部数据。可以对图进行社区检测然后将每个社区聚合为一个“超级节点”进行可视化或者随机采样一个子图。6.3 输出高质量图片用于论文或报告在建模比赛中最终提交的图表需要满足印刷或高清展示的要求。plt.figure(figsize(10, 8)) # 设置画布大小单位是英寸。更大的画布容纳更多细节。 pos nx.spring_layout(G, seed42, k0.15) # 调整k值让节点间距更合适 nx.draw(G, pos, with_labelsTrue, node_size800, font_size12, node_colorskyblue, edge_colordarkgray, width2, font_weightbold) plt.axis(off) plt.tight_layout(pad0.5) # 调整子图参数使图形紧凑且不切边 # 保存为高DPI的矢量或位图格式 plt.savefig(high_quality_graph.png, dpi300, bbox_inchestight) # PNG格式300DPI裁剪空白 # plt.savefig(high_quality_graph.pdf, formatpdf, bbox_inchestight) # PDF矢量格式无限缩放不失真 plt.show()dpi(每英寸点数)用于位图格式如PNG, JPG。论文通常要求300 DPI以上。DPI越高图片越清晰文件也越大。bbox_inchestight自动裁剪图片周围的空白区域让图形充满画布。矢量格式 (PDF, SVG)这是最高质量的选择。矢量图由数学公式定义放大缩小不会失真非常适合论文印刷。用formatpdf或formatsvg保存。6.4 常见“坑”与解决方案节点或边标签重叠这是最常见的问题。除了调整font_size可以尝试不同的布局算法。对于小图可以手动微调pos字典中的坐标。图形显示为空白99%的原因是忘了plt.show()在脚本中或没设置%matplotlib inline在Jupyter中。另外检查一下绘图代码是否在plt.savefig()之后savefig会清空当前图形。颜色映射 (Colormap) 不连续或不符合直觉确保用于映射的数据如权重列表是数值型且范围合理。对于分类数据使用ListedColormap创建离散的颜色映射。有向图箭头太小或看不见检查arrowsize参数并确保arrowsTrue。在nx.draw()中需要设置arrowsTrue在nx.draw_networkx_edges()中默认就是True。图太大布局永远算不完如前所述换用简单布局或对图进行简化。对于超大规模图可视化本身可能就不是最佳分析手段应考虑其他统计摘要方法。通过将这些进阶技巧融入你的绘图流程你产出的将不再仅仅是“示意图”而是能够有效辅助分析、支撑结论、提升作品专业度的“数据可视化作品”。在数学建模中一张精心绘制的图其价值有时不亚于一个复杂的算法。