知识门户

返回

第8章 数据可视化:matplotlib工程图表规范

第三篇:数据与展示

views | comments

第8章 数据可视化:matplotlib工程图表规范#

本章核心理念:一张合格的工程图表,不是”把数据画出来”那么简单——它是测试报告中最有说服力的”证据”,是向老板、客户、同行解释技术方案时最锐利的”武器”。本章教你用 matplotlib 画出能直接放进正式报告的专业图表,以及用 Plotly 在调试阶段快速探索数据


8.1 场景与痛点:默认图表太丑,无法放入正式测试报告#

8.1.1 一个让人尴尬的汇报现场#

上周的项目评审会上,小王打开了一张他用 matplotlib 默认设置画的温升曲线图:

import matplotlib.pyplot as plt
import numpy as np

# 小王的"朴素"代码
x = np.linspace(0, 3600, 3600)
y = 25 + 45 * (1 - np.exp(-x / 800)) + np.random.randn(3600) * 0.3
plt.plot(x, y)
plt.show()
python

这张图的问题清单:

  • 横轴标签3.6e3 这样的科学计数法——没人能一眼看出这是3600秒。
  • 没有标题、没有轴标签——看图的人需要猜”这是温度?还是电压?”
  • 线条太细、颜色太淡——投影仪一打,后排根本看不清。
  • 分辨率太低——截屏粘贴到 Word 里模糊一片。
  • 没有标注关键信息——阈值线在哪?异常区间在哪?峰值是多少?

老板看了一眼,说:“这图能放到发给客户的测试报告里吗?” 小王沉默了。

痛点总结:matplotlib 的默认样式是为”快速查看”设计的,而不是为”正式展示”设计的。工程师需要的是一套可复用的图表规范,让每一张图都能达到”测试报告级”的品质。

8.1.2 我们的目标#

本章结束后,你将能够:

  1. 用一套统一的规范配置,让所有图表自动达到工程报告的品质要求。
  2. 熟练绘制嵌入式场景中最常用的图表类型:时序曲线、多子图对比、双Y轴、异常区域标注。
  3. 用 Plotly 在调试阶段交互式探索数据(缩放、悬停查看数值、动态筛选)。
  4. 清楚地知道什么时候用 matplotlib,什么时候用 Plotly

8.2 核心方法论:工程图表规范#

8.2.1 一次配置,全局生效——工程级样式初始化#

matplotlib 支持 rcParams(runtime configuration parameters),你可以一次性设置全局默认值,之后所有的图表都会自动遵循这些规范。这就像是给你的画笔”调好色盘”。

将以下代码保存为 plot_config.py,在每个绘图脚本开头导入它:

使用方式

import matplotlib.pyplot as plt
import plot_config  # 只需这一行,后续所有 plt 调用自动应用规范

# 从这里开始,你的图表就是"工程级"的了
plt.plot([1, 2, 3], [10, 25, 15])
plt.xlabel('时间 (s)')
plt.ylabel('温度 (°C)')
plt.title('某板卡温升曲线')
plt.savefig('result.png')  # 自动以300 DPI、裁剪白边保存
plt.show()
python

8.2.2 工程图表规范清单#

在正式出图之前,用这张清单逐项自查。它可以打印出来贴在工位上:

序号检查项规范要求常见错误
1中文显示能正常显示中文,不会出现 □ 方块忘记配置 font.sans-serif
2轴标签X轴和Y轴都有标签,且包含物理量名称和单位只写了”温度”,漏了”(°C)“
3标题有简洁明确的标题,说明这张图展示的是什么没有标题,或者标题是 “Figure 1”
4图例多条曲线必须有图例,位置不遮挡关键数据图例挡住了曲线的峰值区域
5刻度刻度值合理,不出现科学计数法(如 3.6e3横轴时间用秒数,显示为 1e3
6网格有淡色辅助网格线,方便读数网格线太浓喧宾夺主,或者没有网格
7分辨率保存图片 ≥ 300 DPI默认72 DPI,打印出来模糊
8配色颜色在彩色和黑白打印下都能区分用了相近的浅色,黑白打印下分不清
9边框隐藏上方和右侧边框(Tufte 数据墨水比原则)四边都画了粗框,视觉噪音大
10图幅图表尺寸适合目标载体(A4纸/投影仪/PPT)默认太小,缩放后看不清

8.2.3 多子图布局:一图胜千言#

当需要对比多个维度的数据时,多子图(subplots)是最常用的布局方式。

基础用法:2行1列布局

进阶布局:不规则网格(GridSpec

当你需要一个大图占上半部分,两个小图并排占下半部分时:

8.2.4 双Y轴:当两个物理量”量纲”不同#

嵌入式测试中经常需要在一张图上展示温度(几十度)和电流(几百毫安),它们的数值范围完全不同。双Y轴是标准做法。

注意事项

  • 两条曲线要使用不同的颜色,且颜色要和对应Y轴的刻度颜色一致,否则看图的人会困惑。
  • 图例要合并放在一个位置,不要分两处。
  • 双Y轴图表容易产生”视觉欺骗”——两条曲线的走势可能因为Y轴刻度范围不同而看起来”相关”或”不相关”,使用时要诚实标注刻度范围。

8.2.5 交互式图表 (Plotly) 快速入门#

matplotlib 的局限#

matplotlib 画出来的是静态图片——你不能缩放局部、不能悬停查看具体数值、不能动态筛选数据范围。在开发调试阶段,你需要快速地、反复地探索数据的细节,这时候静态图片就力不从心了。

Plotly 的杀手级功能#

Plotly 生成的是交互式 HTML 图表,用户可以:

  • 🔍 缩放:鼠标框选任意区域放大查看细节
  • 📍 悬停:鼠标移到数据点上,自动显示精确的 X/Y 值
  • 📊 动态筛选:点击图例隐藏/显示某条曲线
  • 📸 截图:工具栏自带”下载PNG”按钮
  • 💾 导出数据:部分场景下可以直接导出数据点

安装#

pip install plotly
# 如果你使用 Jupyter Notebook,还需要安装:
pip install nbformat
bash

基础用法:3行代码搞定交互式图表#

Plotly 多通道对比#

8.2.6 matplotlib vs Plotly:场景分工决策指南#

这是本节最重要的部分——不是谁比谁好,而是在什么场景用什么工具

维度matplotlibPlotly
输出格式静态图片(PNG, PDF, SVG)交互式 HTML(也可导出静态图片)
最佳场景正式测试报告、论文、PPT、打印文档开发调试阶段的数据探索、在线仪表盘
交互能力无(Jupyter 中有 %matplotlib notebook 但功能有限)缩放、悬停、筛选、动画,开箱即用
精确排版控制极强:像素级控制图表的每个元素较弱:布局由浏览器渲染引擎决定
矢量图导出支持 PDF/SVG,无限放大不失真HTML 本身就是矢量,静态导出支持 SVG
学习曲线API 风格偏底层,需要手动配置较多API 高级封装好,几行代码出漂亮图表
嵌入报告直接插入 Word/LaTeX/PPT需要先导出为静态图片,或嵌入HTML
离线使用完全离线需要浏览器打开 HTML 文件
性能处理百万级数据点表现良好数据量超过10万点时交互可能卡顿

决策流程图

你要画一张图,它的用途是什么?

    ├── 放进正式测试报告 / 论文 / 打印 → matplotlib ✅

    ├── 做 PPT 汇报,需要高清晰度截图 → matplotlib ✅

    ├── 调试阶段,需要反复缩放查看细节 → Plotly ✅

    ├── 要发给同事/客户在线查看 → Plotly (HTML) ✅

    ├── 要做实时数据监控仪表盘 → Plotly (Dash) ✅

    └── 数据量超过10万点 + 需要交互 → matplotlib 画静态概览 
                                     + Plotly 画局部放大(组合使用)
plaintext

实践建议:两者并不冲突,很多工程师的工作流是:

  1. 调试阶段:用 Plotly 快速探索数据,找到感兴趣的模式和异常。
  2. 报告阶段:用 matplotlib 按照工程规范,精确绘制最终的图表。

8.3 核心实战:批量绘制多通道传感器数据曲线#

8.3.1 场景设定#

延续第7章的场景:你有500块板子的温升测试数据。现在需要为每块板子生成一张”测试报告级”的图表,包含:

  • 多通道温度曲线(假设每块板子有3个温度传感器)
  • 供电电压曲线(双Y轴)
  • 温度阈值线和异常区间标注
  • 峰值和均值的统计线
  • 图表标题中包含板子编号和测试时间

500张图,如果手动画,你会画到怀疑人生。所以我们要用脚本批量生成。

8.3.2 完整代码#

8.3.3 代码设计要点#

1. 为什么 plt.close(fig) 是必须的?

批量绘图时,每调用一次 plt.subplots() 就会在内存中创建一个新的 figure 对象。如果你不关闭它,画500张图就意味着同时有500个图表对象驻留在内存中——轻则几GB内存占用,重则程序直接崩溃。

规则:批量绘图必须 plt.close(fig),就像文件读写必须 f.close() 一样。

2. 图表元素的”分层”思维

一张信息丰富的工程图表,可以理解为多层叠加:

第5层: 标注(峰值箭头、注释文字)
第4层: 参考线(阈值线、均值线)
第3层: 异常区间(fill_between 半透明色块)
第2层: 数据曲线(温度线、电压线)
第1层: 坐标轴框架(轴标签、刻度、网格、标题)
plaintext

先画第1层(坐标轴),然后逐层叠加。这个顺序很重要——如果先画数据再画坐标轴,坐标轴会盖住数据。

3. 颜色一致性

每个传感器通道的颜色在整个项目中必须保持一致。这就是为什么我们把颜色定义放在 SENSOR_COLORS 字典里——不管是画单张图还是批量图,NTC_1 永远是红色,NTC_2 永远是蓝色。


8.4 AI协作指南:让AI根据数据特征推荐图表类型并生成绘图代码#

8.4.1 数据特征 → 图表类型的映射#

不同类型的数据显示关系,需要不同类型的图表来表达。当你不确定该用什么图表时,参考以下映射表:

你想展示的数据关系推荐图表类型matplotlib 函数Plotly 函数
随时间变化的趋势折线图plt.plot()go.Scatter(mode='lines')
数据的分布情况直方图、箱线图plt.hist() / plt.boxplot()go.Histogram() / go.Box()
两个变量的关联散点图plt.scatter()go.Scatter(mode='markers')
多个类别的对比柱状图plt.bar()go.Bar()
占比关系饼图、环形图plt.pie()go.Pie()
多维数据的相关性热力图plt.imshow() / sns.heatmap()go.Heatmap()
同一指标多次测量箱线图(对比分布)plt.boxplot()go.Box()

嵌入式工程师最常用的 Top 3

  1. 折线图:温升曲线、电压变化、传感器时序数据(几乎占80%的使用场景)
  2. 散点图:两路传感器的相关性分析(如温度 vs 电流)
  3. 直方图/箱线图:一批产品的测试结果分布(如500块板子的最高温度分布)

8.4.2 万能 Prompt 模板#

8.4.3 AI 审查重点清单#

AI 生成的绘图代码,重点审查以下容易出错的地方:

审查项常见问题正确做法
中文显示没有配置中文字体,输出全是方块在代码开头配置 plt.rcParams['font.sans-serif']
双Y轴图例两个Y轴的图例分开显示,混乱get_legend_handles_labels() 合并到一个 legend() 调用
时间轴格式X轴显示 1.68e9 这样的 Unix 时间戳转为 datetime 类型,用 DateFormatter 格式化
内存泄漏批量绘图时没有 plt.close()循环中每次 plt.savefig() 后紧跟 plt.close(fig)
tight_layout 位置suptitle() 之前调用 tight_layout() 导致标题被裁剪先设置所有标签和标题,最后调用 tight_layout();或者在 savefig 中用 bbox_inches='tight'
颜色对比度多条曲线颜色太接近,黑白打印时分不清使用色相差异大的颜色组合,或配合不同的线型(实线、虚线、点划线)
图例遮挡图例默认放在”最佳位置”但恰好盖住关键数据手动指定 loc='upper left' 等位置,或者放在图外 (bbox_to_anchor)

8.4.4 进阶 Prompt:让AI帮你设计图表风格指南#

当你需要在整个项目(或整个团队)中保持图表风格一致时,可以让 AI 帮你生成一套完整的样式配置文件:


本章小结#

你学到了什么解决了什么问题
rcParams 全局样式配置告别默认样式的”丑图”,一次配置,全局生效
工程图表规范清单10项自查标准,确保每张图都能放进正式报告
多子图布局与 GridSpec在一张图中展示多个维度的数据对比
双Y轴图表在同一张图中展示量纲不同的物理量
Plotly 交互式图表调试阶段快速缩放、悬停查看数据细节
matplotlib vs Plotly 决策指南明确”什么时候用什么工具”,不纠结
批量绘图模板500块板子,一个脚本自动出图
AI Prompt 模板让 AI 根据数据特征推荐图表类型并生成代码

下一章预告:图表让数据”看得见”,但有时候你需要一个实时运行的桌面程序——带按钮、带波形显示、能操作硬件。第9章我们将学习如何用 PyQt5 构建嵌入式上位机,以及那个让无数工程师翻车的致命问题:跨线程更新UI

Comment seems to stuck. Try to refresh?✨