📊 第5章 可视化数据分析图表
📄 一句话概括

标题说「这张图讲什么」,轴标签说「横竖各是什么、单位是什么」。 两条以上的线必须有图例,一条线的图例是废话。 注释用来点出图里最该看的那一处,一张图最多两三条。

📝 本章和前面几章的关系

上一篇把坐标轴收拾干净了。这一篇补上文字:标题、轴标签、图例、注释。 四样齐全,一张图才算能交出去。缺哪一样都可能被追问。

一、标题与轴标签

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 秒实验

  1. 把 tight_layout 注释掉,看标题和纵轴标签有没有被切掉。
  2. 把 loc 改成 'lower right',看图例跑到哪去了。
  3. 想一想:如果图例挡住了数据点,怎么办?

常见误区

  1. 轴标签不写单位:读者得自己猜是元还是万元。
  2. 单条线也加图例:废话,占地方还挡数据。
  3. 注释标了一堆:满图箭头,等于没重点。
  4. 存图前不 tight_layout:标题被切一半,返工重画。
自测三问(点开对答案) 1. 标题和轴标签各回答什么问题? —— 标题答「这张图讲什么」,轴标签答「横竖各是什么、单位是什么」。 2. annotate 的 xy 和 xytext 有什么区别? —— xy 是被指的那个点的坐标,xytext 是文字放的位置。两个位置一般不同。 3. tight_layout 解决什么问题? —— 自动算边距,防止标题、轴标签、刻度被画布边缘切掉。

零件都齐了。下一篇开始画具体图形:先是最常用的折线图和柱形图。

相关笔记