
个人主页杨利杰YJlio❄️个人专栏《Sysinternals实战教程》 《Windows PowerShell 实战》 《WINDOWS教程》 《IOS教程》《微信助手》 《锤子助手》 《Python》 《Kali Linux》《那些年未解决的Windows疑难杂症》让复杂的事情更简单让重复的工作自动化《超简单用 Python 让 Excel 飞起来》读书笔记第7章 案例04 举一反三 添加图例1. 问题背景为什么图例很重要2. 适用场景哪些图表必须加 legend3. 最小可用label legend4. legend 位置设置loc 放对地方5. 图例太大/太挤怎么办fontsize ncol6. 组合图示例柱形图 折线图加 legend7. 图例遮挡数据的终极解决放到图外8. 常见问题与踩坑提醒8.1 调用了 legend 但图例不显示8.2 图例显示乱码8.3 图例挡住关键数据8.4 图例太多太乱9. 我的总结提升1. 问题背景为什么图例很重要这一篇继续整理《超简单用 Python 让 Excel 飞起来》第 7 章中的数据可视化内容主题是在 Matplotlib 图表中添加图例 legend。如果图表里只有一条线、一组柱子图例不是必须的但只要图表里出现两组以上数据图例就变成了读图的关键。我在做办公报表、运维趋势图、工单分析图时最怕看到一种图线很多、颜色很多但没有任何说明。读者只能猜这条线是网络工单还是软件工单这根柱子代表当月数量还是移动平均这块面积到底是哪一类图例 legend 的作用就是把图表中的颜色、线型、柱子和真实业务含义对应起来。它不是装饰而是多数据图表的导航栏。这张图展示了图例的重要性没有 legend 时多数据图表很容易变成“猜谜游戏”。从这张图中可以看出同样是一张多数据图有图例和没有图例的阅读体验完全不同。没有图例时读者只能看见不同颜色的线却不知道它们分别代表什么有了图例之后颜色和业务对象之间建立了明确关系。只要图表中有两条以上数据序列就不要省略图例。否则图表看似完整实际表达是不完整的。2. 适用场景哪些图表必须加 legendlegend 最常见的使用场景是一张图里同时展示多个对象。比如两条折线、多组柱子、柱线组合图、叠加面积图、多个散点序列等。常见场景包括1. 双折线图网络工单 vs 软件工单 2. 多折线图多个产品或多个部门的趋势对比 3. 组合图柱形图表示数量折线图表示移动平均 4. 面积图不同类别叠加展示结构变化 5. 多组柱形图不同部门、月份、指标之间的交叉对比legend 的处理流程可以简单理解为先给每组数据起名字再让 Matplotlib 把这些名字显示出来。否是准备多组数据绘图时设置 label调用 plt.legend图例是否遮挡数据保留当前位置调整 loc 或 bbox_to_anchor优化 fontsize / ncol输出可读图表推荐把 legend 当成图表交付前的必查项。图表不是给自己看的而是给读者看的只要读者需要猜它就还不够清楚。3. 最小可用label legendMatplotlib 中添加图例最基础的方法只有两步第一绘图时给每组数据设置label第二绘图完成后调用plt.legend()显示图例。这张图展示了 legend 的最小可用写法先写label再调用legend()。从这张图中可以看出label是图例内容的来源legend()是让图例显示出来的动作。如果只写legend()但前面没有设置label图例就没有可显示的有效内容。示例代码如下importmatplotlib.pyplotasplt plt.rcParams[font.sans-serif][SimHei]plt.rcParams[axes.unicode_minus]Falsemonths[1月,2月,3月,4月,5月,6月]net[35,30,28,26,24,22]software[40,45,50,55,52,58]plt.figure(figsize(10,6))plt.plot(months,net,markero,label网络工单)plt.plot(months,software,markero,label软件工单)plt.title(双折线图图例 legend 示例)plt.xlabel(月份)plt.ylabel(数量单)plt.legend()plt.grid(axisy,linestyledashed,alpha0.4)plt.tight_layout()plt.show()这里最关键的是这两行plt.plot(months,net,markero,label网络工单)plt.plot(months,software,markero,label软件工单)然后通过下面这句显示图例plt.legend()label 决定图例写什么legend 决定图例是否显示。这是 Matplotlib legend 最基础、也是最常用的逻辑。不要把 label 写成 data1、data2、line1 这种没有业务意义的名字。图例的目的不是证明你写了代码而是让读者知道每条线代表什么。4. legend 位置设置loc 放对地方legend 能显示出来只是第一步放在哪里才是真正影响读图体验的地方。图例如果挡住了关键数据点反而会降低图表质量。这张图展示了loc参数对图例位置的控制效果图例可以放在左上、右上、左下、右下等位置。从这张图中可以看出图例放对位置读图效率会明显提升。图例如果压住曲线、数据点或关键峰值就会让读者分心。常用写法如下plt.legend(locupper left)常用位置可以直接记住下面几个loc 参数含义适合场景upper left左上角右侧数据更密集时upper right右上角左侧数据更密集时lower left左下角上方数据密集时lower right右下角左下数据少时best自动选择较优位置初学者或快速出图时我最常用的是plt.legend(locbest)如果不确定放哪里可以先用locbest让 Matplotlib 自动选择相对不遮挡的位置。后续再根据截图效果微调。不要机械固定使用 upper left。如果左上角正好是数据变化最关键的位置图例就会遮挡关键信息。5. 图例太大/太挤怎么办fontsize ncol当图表中的类别很多时legend 容易变成一大长条。比如 8 个部门、10 个故障类型、20 个产品线如果图例不优化很容易占据大量画布空间。这张图展示了图例过多时的优化思路通过fontsize调整字体大小通过ncol将图例分成多列。从这张图中可以看出优化前图例又长又挤容易压缩图表主体优化后图例分成多列整体更规整阅读也更轻松。常用写法如下plt.legend(locupper left,fontsize10,ncol2)参数含义如下参数作用fontsize控制图例字体大小ncol控制图例显示为几列loc控制图例整体位置如果类别更多也可以尝试plt.legend(locupper left,fontsize8,ncol3)图例类别较多时优先考虑 ncol 分列而不是无限缩小字体。字体太小会降低可读性尤其是截图放到博客或 PPT 之后读者很难看清。如果 legend 已经明显影响图表主体就不要继续硬塞在图内。这种情况更适合把图例移动到图外。6. 组合图示例柱形图 折线图加 legend组合图是 legend 最容易体现价值的场景之一。比如柱形图表示当月工单量折线图表示 3 期移动平均。如果没有图例读者很难判断柱子和折线分别代表什么。下面这段代码演示了柱形图和折线图共用一个 legend 的写法importmatplotlib.pyplotaspltimportpandasaspd plt.rcParams[font.sans-serif][SimHei]plt.rcParams[axes.unicode_minus]Falsemonths[1月,2月,3月,4月,5月,6月]tickets[120,98,135,110,150,160]ma3pd.Series(tickets).rolling(3).mean().tolist()plt.figure(figsize(10,6))plt.bar(months,tickets,label当月工单量,edgecolorblack,alpha0.85)plt.plot(months,ma3,markero,linewidth2,label3期移动平均)plt.title(组合图柱形图 折线图 legend 示例)plt.xlabel(月份)plt.ylabel(数量单)plt.legend(locupper left)plt.grid(axisy,linestyledashed,alpha0.4)plt.tight_layout()plt.show()这段代码里柱形图和折线图都设置了labelplt.bar(months,tickets,label当月工单量)plt.plot(months,ma3,label3期移动平均)只要不同图形对象都设置 labellegend 就可以统一显示。这也是 Matplotlib 比较方便的一点不管是柱子、线、散点只要有 label都能被 legend 管理。组合图中必须加 legend。因为组合图通常表达的是不同类型指标如果没有图例读者无法准确理解图表含义。7. 图例遮挡数据的终极解决放到图外有些图表数据区域非常满legend 不管放左上、右上、左下还是右下都会挡住一部分数据。这时不要继续在图内纠结位置直接把图例放到图外更干净。这张图展示了把图例移动到图外的效果核心参数是bbox_to_anchor。从这张图中可以看出图例移到图外后数据区域更加清晰曲线不会被遮挡图表主体也更适合截图和汇报。常用写法如下plt.legend(locupper left,bbox_to_anchor(1.02,1.0),borderaxespad0)plt.tight_layout()这里重点解释两个参数参数说明locupper left表示图例自身的左上角作为定位点bbox_to_anchor(1.02, 1.0)表示把图例锚定到坐标轴右侧稍微偏外的位置如果你发现图例被裁剪可以配合调整画布大小plt.figure(figsize(12,6))保存图片时也可以这样写plt.savefig(legend_outside.png,dpi200,bbox_inchestight)正式交付的图表如果 legend 遮挡数据我更推荐直接放到图外。这比反复寻找一个“不太挡”的位置更稳定。注意legend 放到图外后一定要检查保存出来的图片是否完整。如果没有使用bbox_inchestight或没有调整画布大小图例可能会被裁掉。8. 常见问题与踩坑提醒8.1 调用了 legend 但图例不显示最常见原因是绘图时没有写label。plt.plot(months,net)plt.legend()上面这种写法没有给数据命名legend 就没有有效内容。正确写法是plt.plot(months,net,label网络工单)plt.legend()legend 不是自动猜业务含义它只显示你通过 label 提供的信息。8.2 图例显示乱码如果图例中的中文显示为方块通常是字体问题。Windows 环境下可以加入plt.rcParams[font.sans-serif][SimHei]plt.rcParams[axes.unicode_minus]False也可以尝试plt.rcParams[font.sans-serif][Microsoft YaHei]8.3 图例挡住关键数据优先使用plt.legend(locbest)如果还是挡住再考虑plt.legend(locupper left,bbox_to_anchor(1.02,1.0))8.4 图例太多太乱优先减少类别数量其次再优化显示形式。plt.legend(fontsize8,ncol2)如果类别太多图例优化只能缓解问题不能从根上解决问题。图表表达本身也需要控制信息密度。9. 我的总结提升这一节的核心不是简单记住plt.legend()而是理解 legend 在图表表达中的位置。只要图表中存在多组数据legend 就承担着“解释颜色、线型、柱子含义”的责任。我把 legend 的使用总结成四句话1. 多数据图必须加 legend。 2. 先写 label再调用 legend。 3. 图例不能遮挡关键数据。 4. 类别多时要么分列显示要么放到图外。图例的本质是让图表脱离作者本人也能被正确理解。一张图如果只有你自己知道每条线代表什么那它还没有达到交付标准。后续写自动化报表时我建议把 legend 位置、字体大小、图例列数这些参数统一封装进绘图函数。这样每次出图都能保持风格一致也减少重复调参。不要把图例当成可有可无的小组件。在多数据图表里legend 直接决定读者能不能看懂图。返回顶部