标题说「这张图讲什么」,轴标签说「横竖各是什么、单位是什么」。 两条以上的线必须有图例,一条线的图例是废话。 注释用来点出图里最该看的那一处,一张图最多两三条。
上一篇把坐标轴收拾干净了。这一篇补上文字:标题、轴标签、图例、注释。 四样齐全,一张图才算能交出去。缺哪一样都可能被追问。
一、标题与轴标签
ax.set_title('上半年销售额')、ax.set_xlabel('月份')、ax.set_ylabel('金额(元)')。
标题说这张图讲什么,轴标签说横竖各是什么、单位是什么。
少了单位就是没写完。「金额」和「金额(元)」差别很大。
fontsize 可以调,但同一张图里字号别超过三级:标题一级、标签一级、刻度一级。
二、图例:legend
label 写在 plot 里,ax.legend() 统一调出来,loc 管位置。
loc 可以是 'upper left'、'lower right'、'best' 这些字符串。
'best' 会自己找一块最空的区域放图例,多数时候好用。
两条以上的线必须有图例。只有一条线时图例是废话,标题里说清就行。
图例挡住数据时,可以设 framealpha=0 去掉底色,或者干脆挪到图外。
三、注释:annotate
ax.annotate('最高点', xy=(5, 162000), xytext=(3, 158000), arrowprops=...)。
xy 是被指的坐标,xytext 是文字放的位置,arrowprops 画箭头。
六月是最高点 162000,箭头指过去,读者不用自己对刻度。
注释用来点出「图里最该看的那一处」。一张图最多两三条,多了就成噪点。
四、挤在一起:tight_layout
图小标题长的时候,标题会被切掉、纵轴标签会被挤出去。
fig.tight_layout() 一行解决:自动算边距,让所有元素都进画面。
它在存图之前调,多子图时更要调。
存图前先 tight_layout。这一行能救掉八成「标签被切掉」的问题。
更精细的控制用 fig.subplots_adjust(left=..., right=...),一般用不上。
五、动手 Demo:文本标签、标题、图例与注释
先补齐标题和轴标签,再给两条线加图例,最后用箭头注释最高点。 末尾对比一张没有 tight_layout 的图,看标题被切掉多少。
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
M = [128000, 116000, 143000, 151000, 138000, 162000]
MON = ["一月", "二月", "三月", "四月", "五月", "六月"]
fig, ax = plt.subplots(figsize=(6.5, 4))
ax.plot(range(6), M, label="今年", marker="o")
ax.plot(range(6), [m * 1.1 for m in M], label="去年", marker="s")
ax.set_xticks(range(6))
ax.set_xticklabels(MON)
ax.set_title("上半年销售额", fontsize=14)
ax.set_xlabel("月份")
ax.set_ylabel("金额(元)")
ax.legend(loc="upper left")
ax.annotate("最高点", xy=(5, 162000), xytext=(3, 158000),
arrowprops=dict(arrowstyle="->"))
fig.tight_layout()
fig.savefig("labels.png")
print("存好 labels.png")
实跑输出:
--------------------------------------------------------------------
文本标签、标题、图例与注释
--------------------------------------------------------------------
① 标题与轴标签
--------------------------------------------------------------------
标题说「这张图讲什么」,轴标签说「横竖各是什么、单位是什么」。
少了单位就是没写完。「金额」和「金额(元)」差别很大。
! 三样齐全(标题、横轴标签、纵轴标签),图才算交代清楚。
② 图例:legend
--------------------------------------------------------------------
label 写在 plot 里,legend 统一调出来。loc 管位置。
loc 可以是 upper left、lower right、best 这些字符串,也可以给编号。
! 两条以上的线必须有图例。只有一条线时图例是废话,标题里说清就行。
③ 注释:annotate
--------------------------------------------------------------------
xy 是被指的坐标,xytext 是文字放的位置,arrowprops 画箭头。
六月是最高点 162000,箭头指过去,读者不用自己去对刻度。
! 注释用来点出「图里最该看的那一处」。一张图最多两三条,多了就成噪点。
④ 挤在一起怎么办:tight_layout
--------------------------------------------------------------------
图小标题长的时候,标题会被切掉、纵轴标签会被挤出去。
fig.tight_layout() 一行解决:自动算边距,让所有元素都进画面。
! 存图前先 tight_layout。这一行能救掉八成「标签被切掉」的问题。
xytext=(3, 158000) 是「文字放在 3 号点、高度 158000 的位置」,和 xy 是两回事。
箭头指错了多半是 xy 和 xytext 弄反。记住 xy 是被指的那个点。
30 秒实验
- 把 tight_layout 注释掉,看标题和纵轴标签有没有被切掉。
- 把 loc 改成 'lower right',看图例跑到哪去了。
- 想一想:如果图例挡住了数据点,怎么办?
常见误区
- 轴标签不写单位:读者得自己猜是元还是万元。
- 单条线也加图例:废话,占地方还挡数据。
- 注释标了一堆:满图箭头,等于没重点。
- 存图前不 tight_layout:标题被切一半,返工重画。
自测三问(点开对答案)
1. 标题和轴标签各回答什么问题? —— 标题答「这张图讲什么」,轴标签答「横竖各是什么、单位是什么」。 2. annotate 的 xy 和 xytext 有什么区别? —— xy 是被指的那个点的坐标,xytext 是文字放的位置。两个位置一般不同。 3. tight_layout 解决什么问题? —— 自动算边距,防止标题、轴标签、刻度被画布边缘切掉。零件都齐了。下一篇开始画具体图形:先是最常用的折线图和柱形图。
- ☐ (本篇完,下一篇 5.6 折线图与柱形图)