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

set_xticks 给位置,set_xticklabels 给文字,两步配合才换得掉标签。 xlim 和 ylim 管显示范围。截断纵轴能让差异显形,也能骗人。 刻度密度用 Locator 调。默认会挑「好看」的数,但间隔未必是你想要的。

📝 本章和前面几章的关系

上一篇的图横轴是 0 到 5,看不懂。这一篇把刻度换成月份,还能调范围。 刻度是图上唯一「直接读数」的入口,它错了整张图就错了。

一、换刻度文字:两步走

ax.set_xticks(range(6)) 定位置,ax.set_xticklabels([...]) 定文字。 只给 labels 不给 ticks 会错位。位置和文字是两件事,必须成对给。 刻度数量要和数据点对上。六个点给六个标签,多一个少一个都会错。

这一步最常出错的地方是「标签数不等于刻度数」,报错信息还不太好懂。

二、显示范围:xlim 与 ylim

默认纵轴从 0 起,六个月的起伏被压成一条近乎水平的线。 把 ylim 设成 100000 到 170000,起伏立刻看得见了——162000 和 116000 的差距一下子显形。 截断纵轴能让差异显形,也能骗人。同一张图换个 ylim,结论看起来完全不同。

所以柱形图的纵轴必须从 0 起(柱长就是数值),折线图可以截断但必须标出来。

三、刻度密度:Locator

默认的自动刻度会挑 1、2、5 的倍数,间隔未必符合你的需要。 ax.yaxis.set_major_locator(MultipleLocator(20000)) 一给,纵轴每两万一个刻度。 这样刻度是 100000、120000、140000、160000,读数时心算也方便。

要给别人看的图,刻度间隔自己定。默认值只保证「不难看」,不保证「好用」。

四、网格与边框

ax.grid(True, linestyle='--', alpha=0.5) 打开网格,虚线半透明。 太实的网格会盖过数据线,读者第一眼看到的是格子不是数据。 常见做法:只留横向网格。人读纵轴的值更费劲,横线能帮上忙。

网格是给读数用的,不是装饰。没有网格也行,但别画得比线还显眼。

五、动手 Demo:坐标轴与刻度

先换掉横轴标签,再调纵轴范围看差异怎么显形,最后调刻度间隔加网格。 重点是「同一份数据,换个 ylim,看起来完全不同」这件事。

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator

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, 4))
ax.plot(range(6), M, marker="o")
ax.set_xticks(range(6))
ax.set_xticklabels(MON)
ax.set_ylim(100000, 170000)
ax.yaxis.set_major_locator(MultipleLocator(20000))
ax.grid(True, linestyle="--", alpha=0.5)
fig.tight_layout()
fig.savefig("ticks.png")
print("纵轴 %s" % (ax.get_ylim(),))
print("刻度 %s" % ([t.get_text() for t in ax.get_xticklabels()],))

实跑输出:

--------------------------------------------------------------------
坐标轴与刻度
--------------------------------------------------------------------

  ① 刻度位置和刻度文字:xticks
  --------------------------------------------------------------------
  set_xticks 给位置,set_xticklabels 给文字,两步配合才换得掉标签。
  只给 labels 不给 ticks 会报错或错位——位置和文字是两件事。
  ! 刻度数量要跟数据点对上。6 个点给 6 个标签,多一个少一个都会错位。

  ② 显示范围:xlim 和 ylim
  --------------------------------------------------------------------
  默认纵轴从 0 起,六个月的起伏被压成一条近乎水平的线。
  把 ylim 设成 100000 到 170000 之后,起伏立刻看得见了。
  ! 截断纵轴能让差异显形,也能骗人。同一张图换个 ylim,结论看起来完全不同。

  ③ 刻度密度:locator
  --------------------------------------------------------------------
  MultipleLocator(20000) 让纵轴每两万一个刻度,比默认的自动生成整齐。
  默认的自动刻度会挑「好看」的数(1、2、5 的倍数),但间隔未必是你想要的。
  ! 要给别人看的图,刻度间隔自己定,别全交给默认值。

  ④ 网格线与边框
  --------------------------------------------------------------------
  grid 打开网格,alpha 调透明度。太实的网格会盖过数据线。
  网格是给读数用的,不是装饰。没有网格也行,但别画得比线还显眼。
  ! 常见做法:横网格留、纵网格删。因为人读纵轴的值更费劲。

get_ylim() 返回的是一个元组,元组套进 % 会被当成参数表。要写成 % (值,)。 set_xticklabels 之后要 tight_layout。长标签会被挤出画面。

30 秒实验

  1. 把 set_ylim 那行注释掉,看同一份数据变成什么样子。
  2. 把 MultipleLocator(20000) 改成 5000,看刻度密到什么程度就挤了。
  3. 想一想:柱形图能不能也把 ylim 设成不从 0 开始?为什么?

常见误区

  1. 只调 labels 不调 ticks:标签数量对不上,报错或错位。
  2. 柱形图截断纵轴:柱长不再代表数值,等于撒谎。
  3. 刻度太密:数字叠在一起,比没有刻度还难读。
  4. 网格画成实线深色:数据线被网格盖住,主次颠倒。
自测三问(点开对答案) 1. 换刻度文字为什么要两步? —— 一步管位置(ticks),一步管文字(ticklabels)。位置决定标在哪,文字决定写什么。 2. 为什么柱形图的纵轴必须从 0 起? —— 柱子的长度直接代表数值大小,截断之后长度比例就假了。折线只看位置,可以截。 3. MultipleLocator 和 set_yticks 有什么区别? —— set_yticks 是给死一组位置,MultipleLocator 是给「间隔」,范围变了它自动铺满。

坐标轴对上了,但图上还缺标题、单位和图例。下一篇把这些补齐。

相关笔记