Matplotlib 的套路就三步:造画布、画、存(或显示)。 fig, ax = plt.subplots() 一行拿到「纸」和「图」,后面所有操作都在 ax 上。 不写 plt.show() 也能存图。没有显示器的机器上,show 什么都不干。
上一篇讲选什么图,这一篇讲怎么把图画出来。工具是 Matplotlib。 本机 matplotlib 3.11.1,后端用 Agg(没有显示器),所有图存成 PNG。
一、三步走
第一步 fig, ax = plt.subplots(),第二步 ax.plot(x, y),第三步 fig.savefig()。
三行代码,一张折线图就出来了,存成 PNG 26524 字节。
fig 是纸,ax 是纸上的图。后面调标题、调刻度,全在 ax 上做。
要调整张纸(尺寸、边距、一张纸贴几块图),才动 fig。
二、x 不给会怎样
ax.plot([88, 92, 75, 85, 90]) 只给一组数,x 自动取 0 到 4。
所以第一个点横坐标是 0,不是 1。这一点在标刻度的时候会咬人。
想从 1 开始就自己给 x。ax.plot(range(1, 6), y),一步到位。
三、两种写法:面向对象与 pyplot
| 写法 | 长什么样 | 什么时候用 |
|---|---|---|
| 面向对象 | ax.plot / ax.set_title | 多子图、要精细控制 |
| pyplot | plt.plot / plt.title | 单张图、快速看 |
两种都能出图,结果一样。区别是 plt.plot 作用在「最后一个」axes 上。
一张纸上有四块图时,plt.plot 只画到最后那块,前面三块不动。
多子图一律用面向对象写法。单张图用哪种都行,但别在同一个脚本里混着用。
四、看图的时候先看什么
先看形状:是往上走、往下走,还是平的?有没有突跳、有没有缺口? 再看坐标:纵轴从几开始?刻度间隔多少?单位是什么? 顺序不能反。先看坐标容易被数字带走,反而看不见整体形状。
纵轴不从 0 开始时,一点小起伏会被放大几十倍,看起来像暴跌。
五、动手 Demo:Matplotlib 初体验:第一张图
画一条五个点的折线,标上标题和轴标签,存成 PNG 并打出字节数。 再用 pyplot 写法画一张一样的,对比两种写法。
import os
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
fig, ax = plt.subplots(figsize=(6, 4))
ax.plot([1, 2, 3, 4, 5], [88, 92, 75, 85, 90], marker="o")
ax.set_title("语文成绩折线")
ax.set_xlabel("序号")
ax.set_ylabel("分数")
fig.savefig("first.png")
print("字节 %d" % os.path.getsize("first.png"))
plt.figure()
plt.plot([1, 2, 3], [3, 1, 2])
plt.savefig("pyplot.png")
print("pyplot 版 %d 字节" % os.path.getsize("pyplot.png"))
实跑输出:
--------------------------------------------------------------------
Matplotlib 初体验:第一张图
--------------------------------------------------------------------
① 三步:造画布、画、存
--------------------------------------------------------------------
第一张图存成 26524 字节。
fig, ax = plt.subplots() 一行拿到「纸」和「图」,后面所有操作都在 ax 上做。
plot 只给一组 y 值时,x 自动用 0 到 n-1。所以第一个点是 0 号,不是 1 号。
! 不写 plt.show() 也能存图。没有显示器的机器上,show 什么都不干。
② 两种写法:面向对象与 pyplot
--------------------------------------------------------------------
上面是面向对象(ax.plot),下面是 pyplot(plt.plot)。两种都能出图。
plt.plot 作用在「最后一个」axes 上。一张纸上有好几块图时,它只认最后那块。
! 多子图一律用面向对象写法。单张图用哪种都行,但别混着用。
③ 看图的时候看什么
--------------------------------------------------------------------
这张图三个点:(0,3)、(1,1)、(2,2)。中间的谷底在 x=1。
先看形状,再看坐标。形状对了再看具体数值,否则容易被刻度误导。
! 纵轴不从 0 开始时,起伏会被放大几十倍——看起来「暴跌」,其实只差一点点。
matplotlib.use('Agg') 要在 import pyplot 之前调,顺序反了不生效。
font.sans-serif 设成 SimHei 才能写中文。不设的话中文全是方块。
30 秒实验
- 把 marker 去掉,看折线变成什么样子。
- 把 savefig 的文件名改成 .pdf,看字节数怎么变。
- 想一想:如果不写 figsize,图会有多大?改一下量一量。
常见误区
- 以为必须 plt.show():没有显示器的机器上它什么都不干,存图才管用。
- 用 Agg 之前先 import pyplot:后端设不上,有些环境会直接报错。
- 忘了设中文字体:标题里的中文全变成方块。
- x 不给就以为从 1 开始:默认从 0 起,标刻度时会错一位。
自测三问(点开对答案)
1. Matplotlib 的三步是哪三步? —— 造画布(subplots)、画(plot)、存(savefig)。显示是第四步,但在服务器上可以省。 2. fig 和 ax 各是什么? —— fig 是整张纸,管尺寸和布局;ax 是纸上的那块图,管数据、标题、刻度。 3. 为什么要设 font.sans-serif? —— Matplotlib 默认字体不带中文,不换字体所有中文都渲染成方块。第一张图出来了。下一篇讲画布本身:尺寸、清晰度、一条线里放多组数据。
- ☐ (本篇完,下一篇 5.3 plot 函数与画布)