知识点思维导图
28 个知识节点
参考资料
Python(22) - 数据可视化
读完后,你应能完成以下任务:
- 绘制“Python(22) - 数据可视化 / 先建立前端锚点”的关键对象与数据流,解释“差别在于——ECharts 是"声明式塞一份 option",matplotlib 更像"命令式地往画布上一笔一笔画"。”,并用源码位置、日志或 Trace 标注证据。
- 为“Python(22) - 数据可视化 / 最小可用:三行画一条折线”设计正常与异常输入,验证“记住这个对照:ECharts 是一份 option 对象,matplotlib 是一串 plt.xxx() 调用,最后 show() 等价于 ECharts 渲染到 DOM。”,输出首个偏差位置与回归测试结果。
- 实现“Python(22) - 数据可视化 / 关键:matplotlib 有两套 API,别学混”的最小代码或配置,检验“新手看 matplotlib 教程最容易懵,是因为网上代码混用了两种写法。”,输出命令、结果与 Diff,并说明不适用边界。
你在前端画图,第一反应是 ECharts / Chart.js / D3:给个容器、塞一份
option配置、它就渲染出图。Python 这边对标的就是 matplotlib——数据科学界事实上的"画图标准库",Pandas、NumPy 的结果几乎都靠它出图。本篇解决三个问题:怎么把一组数字快速画成折线/柱状/散点;matplotlib 那套"看起来很乱"的 API 到底分几种、该用哪种;以及在没有屏幕的后端服务器上怎么把图存成文件。
一、先建立前端锚点
| 你在前端这么做 | matplotlib 对应 | 说明 |
|---|---|---|
import * as echarts from 'echarts' |
import matplotlib.pyplot as plt |
引入画图库 |
echarts.init(dom) 拿到实例 |
fig, ax = plt.subplots() 拿到画布+坐标系 |
创建图 |
chart.setOption({...}) |
ax.plot(x, y) / ax.bar(...) |
往图里塞数据 |
| 浏览器自动渲染到页面 | plt.show()(弹窗)或 fig.savefig(...)(存文件) |
输出 |
arr.map(...) 处理完数组再喂给图表 |
df.plot()(Pandas 直接出图) |
数据→图一步到位 |
核心切入点:matplotlib ≈ 后端版的 ECharts/D3。差别在于——ECharts 是"声明式塞一份 option",matplotlib 更像"命令式地往画布上一笔一笔画"。理解了这个差异,后面那套看着零散的 API 就顺了。
安装:
pip install matplotlib。它常和 NumPy(第 20 篇)、Pandas(第 21 篇)一起用,画图的数据来源通常就是它们。
二、最小可用:三行画一条折线
对照你熟悉的 ECharts,本质是同一件事,只是 matplotlib 把"配置"拆成了一行行函数调用:
// ECharts 等价写法:一份声明式 option 塞进去
chart.setOption({
xAxis: { data: [1, 2, 3, 4, 5] },
yAxis: {},
series: [{ type: 'line', data: [2, 5, 3, 8, 7] }]
})
记住这个对照:ECharts 是一份 option 对象,matplotlib 是一串 plt.xxx() 调用,最后 show() 等价于 ECharts 渲染到 DOM。
三、关键:matplotlib 有两套 API,别学混
新手看 matplotlib 教程最容易懵,是因为网上代码混用了两种写法。务必先分清:
3.1 pyplot 状态机接口(plt.xxx)—— 像全局单例画布
plt.plot()、plt.title() 这类直接挂在 plt 上的函数,背后操作的是一个全局"当前图"。你不用拿到任何对象,所有调用都默默作用在那块隐藏的画布上。
这种风格类比 JS 里操作一个全局 canvas 单例:你不传引用,函数内部自己找那块全局画布。写一次性脚本很爽,但多张图并存时容易画串。
3.2 面向对象接口(fig, ax)—— 像拿到 DOM 节点再操作
更推荐、也更可控的写法:先 plt.subplots() 拿到 fig(整张画布)和 ax(坐标系),之后所有操作都明确作用在 ax 上。
这就像前端里 const dom = document.getElementById('chart') 拿到节点再操作,而不是依赖某个全局状态。多子图、复杂布局、在函数里画图返回,一律用 OO 接口。
| 状态机接口 | OO 接口 | 类比 |
|---|---|---|
plt.plot(...) |
ax.plot(...) |
全局 canvas vs 拿到的 DOM 节点 |
plt.title(...) |
ax.set_title(...) |
注意 OO 多了 set_ 前缀 |
plt.xlabel(...) |
ax.set_xlabel(...) |
同上 |
| 适合:一次性脚本、Jupyter 速画 | 适合:多图、库代码、可控布局 | —— |
边界提醒:两套 API 别在同一段代码里乱混。新手常见错误是先
fig, ax = plt.subplots()又去调plt.title(),结果标题加到了"当前图"而不是你的ax上,看着没生效。本篇之后统一用 OO 接口。
四、四种最常用的图
数据可视化 90% 的场景就这几种。下面都用 OO 接口。
4.1 折线图(趋势)—— ax.plot
4.2 柱状图(对比)—— ax.bar
4.3 散点图(相关性)—— ax.scatter
4.4 直方图(分布)—— ax.hist
直方图和柱状图不一样:柱状图是"每个分类一根柱",直方图是"把连续数据切成若干区间(bin),统计每段落了多少个",用来看分布。
| 图类型 | 函数 | 用来回答 | ECharts 里的 type |
|---|---|---|---|
| 折线 | ax.plot |
随时间怎么变 | line |
| 柱状 | ax.bar |
各类别谁高谁低 | bar |
| 散点 | ax.scatter |
两个量有无相关 | scatter |
| 直方 | ax.hist |
数据怎么分布 | 无直接对应,需自己分桶 |
五、常见定制:标题、坐标、图例、多线
一张图常常要画多条线、加网格、调范围。这些都是 ax 上的方法:
要点:多条线 = 在同一个 ax 上多次 plot,每条给不同 label,最后 ax.legend() 一次性显示图例。这和 ECharts 往 series 数组里塞多项是一个意思。
六、显示 vs 保存:后端服务器没有屏幕
这是前端转后端最容易踩的点。plt.show() 是要"弹窗"的,但你的代码常常跑在没有图形界面的服务器上(比如 FastAPI 接口里生成报表图)。这时候不能 show(),要直接存成文件。
6.1 保存为图片
注意:
savefig要在show()之前调用。因为show()在某些环境下会清空当前图,之后再 save 可能得到空白图。
6.2 无界面环境:切 Agg 后端
如果服务器连图形库都没装,import matplotlib.pyplot 可能直接报错或卡住。解决办法是在导入 pyplot 之前指定一个不依赖屏幕的后端 Agg:
类比理解:浏览器里 ECharts 必须有 DOM 容器才能渲染;Agg 后端相当于给 matplotlib 一块"虚拟离屏 canvas",画完直接导出图片,全程不需要真实窗口。
七、和 Pandas 联动:一行出图
实际数据分析里,数据基本都在 Pandas 的 DataFrame 里(第 21 篇)。DataFrame 自带 .plot(),底层就是调 matplotlib,省去手动取列:
df.plot() 会自动把每一列画成一条线、用 index 当横轴、列名当图例——相当于帮你把"取数据 + 配 series"一步做完。快速探查数据时首选它。
八、绕不开的坑:中文显示成方块 □□□
这是中文用户用 matplotlib 的第一个拦路虎:标题、标签里的中文全变成空心方块。WHY:matplotlib 默认字体不含中文字形,找不到就用方块占位。解决办法是显式指定一个系统里有的中文字体:
plt.rcParams 是 matplotlib 的全局配置字典,类比前端的全局主题变量/CSS 变量——改一次,之后所有图都生效。
九、其他易踩的坑
-
两套 API 混用导致设置不生效(第三节已说,重复强调因为最常见)。拿了
ax就一路ax.set_xxx,别中途跳回plt.title。 -
plt.show()在脚本里会阻塞。它会卡住程序直到你手动关掉弹窗,循环里画多张图时尤其坑。批量出图请用savefig不用show。 -
忘了清理导致图越画越乱。状态机接口下连续画多张图,新图会叠在旧图上。要么每次用独立的
fig, ax = plt.subplots(),要么plt.close(fig)关掉上一张释放内存(服务器里循环出图不关会内存泄漏)。 -
Jupyter 里不用
show()也能显示。Notebook 环境自动渲染最后一个图对象,但写成.py脚本就必须show()或savefig(),别把 Jupyter 习惯带到脚本里。 -
直方图
hist当成柱状图bar用。bar要你自己给好每根柱的高度;hist是给它一堆原始数据、它自己分桶统计。搞反了画出来不对。
十、总结
- 先建立前端锚点:| 浏览器自动渲染到页面 | plt.show()(弹窗)或 fig.savefig(...)(存文件) | 输出 |
- 最小可用:三行画一条折线:记住这个对照:ECharts 是一份 option 对象,matplotlib 是一串 plt.xxx() 调用,最后 show() 等价于 ECharts 渲染到 DOM。
- 关键:matplotlib 有两套 API,别学混:新手看 matplotlib 教程最容易懵,是因为网上代码混用了两种写法。
- 四种最常用的图:直方图和柱状图不一样:柱状图是"每个分类一根柱",直方图是"把连续数据切成若干区间(bin),统计每段落了多少个",用来看分布。
- 常见定制:标题、坐标、图例、多线:这和 ECharts 往 series 数组里塞多项是一个意思。
- 显示 vs 保存:后端服务器没有屏幕:这是前端转后端最容易踩的点。
学完自测
选择所有正确答案;提交后逐项核对判断依据。