Skip to content

第 3 章 线图:plot 与坐标轴控制

学习目标

  • 掌握 ax.plot 的基本形式与 fmt 简写
  • 会用关键字参数控制颜色、线型、线宽、标记
  • 在一个坐标系里画多条线并区分
  • set_xlim / set_ylim 控制坐标轴范围
  • set_xticks / set_xticklabels 控制刻度
  • gridaxhline 增强可读性

3.1 plot 的基本形式

ax.plot(x, y)xy 一一对应的点连成折线。最基本的写法:

python
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)

fig, ax = plt.subplots()
ax.plot(x, y)
plt.show()

fmt(format 简写) 是一个字符串,把「颜色 + 线型 + 标记」压缩成一个参数,例如 "b-" 表示蓝色实线、"r--" 表示红色虚线、"g:" 表示绿色点线。它比逐个关键字更短,但可读性稍差:

python
ax.plot(x, np.sin(x), "b-")

更清晰、更常用的做法是用关键字参数:

参数作用示例
color线条颜色color="#d33f49"
linestyle线型"-" 实线、"--" 虚线、":" 点线、"-." 点划线、"None" 无线
linewidth线宽(数字,默认 1)linewidth=2
marker数据点标记"o" 圆点、"s" 方块、"^" 三角、"D" 菱形
markersize标记大小markersize=4

图 3-1 用同一条正弦曲线演示不同的样式组合:

图 3-1 fmt 简写与样式参数

其中第四条线演示了混合写法:color=RED, linestyle="-.", linewidth=2, marker="o"。颜色可以是命名色("blue")、十六进制("#11557c")、RGB 元组等;全书统一用十六进制配色。

3.2 多条线:一图看趋势对比

一个坐标系可以画任意多条线,顺序叠加。用 label 给每条线命名,再用 ax.legend() 显示图例(图例的完整控制在第 7 章):

python
import matplotlib.pyplot as plt
import numpy as np

days = np.arange(1, 8)
high = np.array([28, 31, 33, 30, 29, 32, 34])
low  = np.array([19, 21, 22, 20, 19, 21, 23])
mean = (high + low) / 2

fig, ax = plt.subplots()
ax.plot(days, high, marker="o", label="最高气温")
ax.plot(days, low, marker="s", label="最低气温")
ax.plot(days, mean, marker="^", linestyle="--", label="平均气温")
ax.set_title("一周气温:高、低、平均")
ax.set_xlabel("日期")
ax.set_ylabel("气温(°C)")
ax.legend()
plt.show()

图 3-2 真实输出:

图 3-2 一个坐标系里的多条线

不加 label 的线不会出现在图例里;图例默认放在右上角,可以调整(第 7 章)。

3.3 坐标轴范围:xlim 与 ylim

Matplotlib 会自动根据数据推算坐标轴范围,但自动范围不一定适合你的表达。ax.set_xlim(左, 右) / ax.set_ylim(下, 上) 手动指定范围——这是「放大看局部」的手段。

python
import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(3)
day30 = np.arange(1, 31)
temp30 = 26 + 6 * np.sin(day30 / 30 * 2 * np.pi) + rng.normal(0, 1.5, 30)

fig, axes = plt.subplots(1, 2)
axes[0].plot(day30, temp30)
axes[0].set_title("默认范围")
axes[1].plot(day30, temp30)
axes[1].set_xlim(10, 20)
axes[1].set_ylim(25, 32)
axes[1].set_title("xlim(10, 20) / ylim(25, 32)")
plt.show()

图 3-3 真实输出:左图是自动范围,右图把 x 限到第 10~20 天、y 限到 25~32°C,相当于「放大镜」:

图 3-3 默认范围与手动限定的范围

反向设置(如 set_xlim(20, 10))可以把横轴翻转;set_xlim(right=20) 只改右边界也是允许的。

3.4 刻度:set_xticks 与 set_xticklabels

刻度(tick)是坐标轴上带数字的记号。自动刻度通常够用,但文本类横轴(月份、城市名)需要自定义:

python
import matplotlib.pyplot as plt
import numpy as np

months = ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"]
sales = np.array([12, 18, 21, 25, 30, 35, 33, 38, 41, 45, 42, 50])

fig, ax = plt.subplots()
ax.plot(np.arange(12), sales, marker="o")
ax.set_title("全年销售额")
ax.set_xlabel("月份")
ax.set_ylabel("销售额(万元)")
ax.set_xticks(np.arange(12))
ax.set_xticklabels(months)
plt.show()

图 3-4 真实输出:set_xticks 指定刻度的位置,set_xticklabels 指定每个位置显示的文本:

图 3-4 自定义刻度与刻度标签

对应地,set_yticks / set_yticklabels 控制纵轴。刻度自动生成的规则(定位器 Locator 与格式化器 Formatter)在第 8 章展开。

3.5 网格与参考线

ax.grid(True, ...) 打开网格线,让数值更容易对照;ax.axhline(y) 画一条水平参考线(垂直方向用 ax.axvline(x))。参考线常用来标出阈值:

python
import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(3)
day30 = np.arange(1, 31)
temp30 = 26 + 6 * np.sin(day30 / 30 * 2 * np.pi) + rng.normal(0, 1.5, 30)

fig, ax = plt.subplots()
ax.plot(day30, temp30, label="气温")
ax.axhline(30, color="#d33f49", linestyle="--", linewidth=1.5, label="高温阈值 30°C")
ax.set_title("30 天气温与参考线")
ax.set_xlabel("日期")
ax.set_ylabel("气温(°C)")
ax.legend()
ax.grid(True, alpha=0.3)
plt.show()

图 3-5 真实输出:axhline 画出的虚线把超过 30°C 的天数一眼标出,网格线帮助对位读数:

图 3-5 网格线与水平参考线

alpha=0.3 把网格线的透明度调到 30%,让数据线更突出;axhline 也可以带 alphacolorlinewidth

3.6 读懂报错:颜色写错

color 参数只接受合法的颜色值。写成 "blu"(少一个 e)会报错:

>>> ax.plot(np.linspace(0, 1, 10), color="blu")
Traceback (most recent call last):
  ...
ValueError: 'blu' is not a valid value for color: supported inputs are (r, g, b) and
(r, g, b, a) 0-1 float tuples; '#rrggbb', '#rrggbbaa', '#rgb', '#rgba' strings;
named color strings; string reprs of 0-1 floats for grayscale values; 'C0', 'C1',
... strings for colors of the color cycle; and pairs combining one of the above
with an alpha value

解读:ValueError 列出 Matplotlib 支持的全部颜色形式——RGB 元组、#rrggbb 十六进制、命名颜色、灰度字符串、色环 C0~C9 等。最常见的写法是命名颜色和 #rrggbb。若记不清名字,用 plt.colormaps 或查官方「颜色示例」;或干脆用十六进制,保证不踩坑。

动手实践

  1. np.linspace(0, 10, 200) 生成 x,画 sincos 两条线,分别用实线和虚线,配图例。
  2. 画出图 3-3 的左右对比:默认范围 vs xlim(10, 20)ylim(25, 32)
  3. set_xticksset_xticklabels 把横轴改成「周一周三周五周日」四个刻度。
  4. 画 30 天气温,加 axhline 高温阈值线与网格,复现图 3-5。
  5. 故意把 color 写成不存在的名字,读报错,说出「合法的颜色输入形式」有哪几种。

常见错误

错误写法现象原因
color="blu"ValueError: 'blu' is not a valid value for color颜色名拼错;用命名色或 #rrggbb
fmt="b—" 等非 ASCII 线型无法识别线型只支持 ---:-.None
ax.plot(x, y) 后忘记 ax.legend()没有图例图例要显式调用才会显示
set_xlim(20) 只传一个数不报错,但只改了左边界,右边界不变set_xlim 需要左右两个参数;只想改一边用 left= / right=
ax.plot(x, y, width=2)线宽无变化参数名是 linewidth,不是 width
ax.axhline(y) 忘记指定颜色默认色不明显参考线要显式配色,否则与数据线同色混淆

章末练习

基础

  1. 画一条从 (0, 0)(10, 20) 的红色实线,线宽 3,标记为方块。
  2. sincos 两条线,一条实线一条虚线,加图例。
  3. xlim 设为 (2, 8),ylim 设为 (-1.5, 1.5),画出放大后的 sin

提高

  1. np.linspace 生成 500 个点,画 sin(5x)cos(3x) 两条线,分别配不同线型与颜色,并打开网格。
  2. 画一张「某城市全年 12 个月平均气温」折线图,横轴刻度为 1~12 月,纵轴标签带单位。

挑战

  1. ax.axhliney=0 处画一条参考线,再画 sin(x)cos(x),观察哪段区间 sin > cos;把该区间用 ax.axvspanax.fill_between 高亮(提示:fill_between 见第 6 章)。
  2. 生成两组随机数据(固定种子),用两条线对比趋势;然后用 set_xticks 把横轴改成有意义的标签,并讨论什么情况下「自定义刻度」是必要的。

章末自测

每题选择一个最佳答案。本书不附答案:完成后交由老师或 AI 老师批改讲解。

  1. fmt="r--" 表示?
    • A. 红色实线
    • B. 红色虚线
    • C. 蓝色虚线
    • D. 红色点线
  2. 控制线宽的关键字是?
    • A. width
    • B. linewidth
    • C. thickness
    • D. size
  3. 手动设置横轴范围应使用?
    • A. ax.xlim(0, 10)
    • B. ax.set_xlim(0, 10)
    • C. ax.set_xrange(0, 10)
    • D. plt.lim(0, 10)
  4. ax.set_xticks([1, 3, 5]) 的作用是?
    • A. 把数据点放在 1、3、5
    • B. 设置刻度位置为 1、3、5
    • C. 删除其他数据
    • D. 设置线条宽度
  5. 画一条水平参考线应使用?
    • A. ax.axhline(y)
    • B. ax.axvline(y)
    • C. ax.grid(y)
    • D. ax.hline(y)
  6. 图例需要调用哪个方法才会显示?
    • A. ax.show_legend()
    • B. ax.legend()
    • C. plt.legend_show()
    • D. 自动显示,无需调用
  7. 标记「菱形」对应的 marker 值是?
    • A. "o"
    • B. "s"
    • C. "D"
    • D. "^"
  8. color="#d33f49" 属于哪种颜色写法?
    • A. 命名颜色
    • B. RGB 元组
    • C. 十六进制字符串
    • D. 灰度字符串
  9. ax.grid(True, alpha=0.3)alpha 控制?
    • A. 线条粗细
    • B. 网格线的透明度
    • C. 坐标轴颜色
    • D. 数据点大小
  10. set_ylim(上, 下) 中参数写反(上、下颠倒)会发生?
    • A. 报错
    • B. 纵轴方向翻转
    • C. 没有变化
    • D. 清除纵轴