Matplotlib 第二章 艺术画笔见乾坤

一、概述

1.Matplotlib 三层 API 架构

Matplotlib 的绘图逻辑完全模拟人工作画的流程,分为三层核心 API,各司其职:

API 层级 对应模块 核心作用 类比
底层画布 matplotlib.backend_bases.FigureCanvas 承载所有图像的绘图区域 画纸 / 画布
渲染引擎 matplotlib.backend_bases.Renderer 控制在画布上绘图的具体方式 画笔 / 颜料
图形组件 matplotlib.artist.Artist 定义图表的具体元素(线条、文字、坐标轴等) 作画的内容

2.Artist 的分类

1.primitives(基本要素)

  • 定义:绘图的基础图形对象,是图表的 "原子元素"
  • 常见类型:Line2D(曲线)、Text(文字)、Rectangle(矩形)、Image(图像)等

2. containers(容器)

  • 定义:用来装基本要素的 "盒子",用于组织和管理图形元素
  • 核心类型:
    • Figure:最顶层容器,代表整个图表画布
    • Axes:核心容器,代表带坐标轴的绘图区域(一个 Figure 可以包含多个 Axes)
    • Axis:坐标轴容器,包含刻度、标签等子元素

3.Matplotlib 标准用法

Matplotlib 的标准绘图流程是容器创建 → 元素绘制,步骤清晰且可复用:

标准三步法

  1. 创建 Figure 实例:初始化整个图表画布
  2. 创建 Axes/Subplot 实例:在画布上开辟带坐标轴的绘图区
  3. 用 Axes 方法绘制 primitive:在绘图区添加线条、文字等基础元素

示例(正弦曲线)

复制代码
import matplotlib.pyplot as plt
import numpy as np

# Step 1: 创建 Figure 画布实例
fig = plt.figure()

# Step 2: 在 Figure 上创建 2行1列 的子图,并选中第一个子图
ax = fig.add_subplot(2, 1, 1)

# Step 3: 用 Axes 实例绘制正弦曲线
t = np.arange(0.0, 1.0, 0.01)
s = np.sin(2 * np.pi * t)
# plot 方法返回 Line2D 对象(primitive 类型),lw=2 表示线宽为2
line, = ax.plot(t, s, color='blue', lw=2)

# 显示图表
plt.show()

运行后会生成如下正弦曲线:

二.自定义Artist 对象

1.Artist属性

Matplotlib 所有图表元素都是 Artist 实例,都有可自定义的属性,核心如下:

(1)核心 patch 属性

  • Figure.patch:代表整个图表的矩形背景框,可设置画布的背景色、透明度
  • Axes.patch:代表坐标轴内部的绘图区背景,可设置绘图区的颜色、透明度
  • 两者本质都是 Rectangle 对象,是 Matplotlib 中最基础的容器背景

(2)所有 Artist 通用属性

属性名 作用 取值说明
.alpha 透明度 0(完全透明)~ 1(完全不透明)的浮点数
.axes 所属 Axes 返回该元素绑定的 Axes 对象,无则为 None
.figure 所属 Figure 返回该元素绑定的 Figure 对象,无则为 None
.label 文本标签 用于图例、标注的自定义文本
.visible 显示控制 布尔值,True 显示,False 隐藏该元素

(3) 属性查看与修改

复制代码
# 查看 Figure 和 Axes 的 patch 对象
print(plt.figure().patch)
print(plt.axes().patch)

# 修改 Figure 背景色为浅灰色,透明度0.8
fig = plt.figure()
fig.patch.set_facecolor('#f0f0f0')
fig.patch.set_alpha(0.8)

# 修改 Axes 背景色为白色
ax = fig.add_subplot(111)
ax.patch.set_facecolor('white')
  1. Axes 是核心 :Matplotlib 中 90% 的定制化操作(如设置坐标轴、添加图例、绘制图形)都通过 Axes 实例完成,是学习的重中之重。
  2. 面向对象 vs pyplot 快捷方式
    • 上面的流程是面向对象式写法,适合复杂图表定制;
    • 日常快速绘图可以用 plt.plot() 等 pyplot 快捷函数,本质是对面向对象 API 的封装。
  3. 属性修改方法 :所有 Artist 属性都可以通过 set_xxx() 方法修改,比如 line.set_color('red')ax.set_title('正弦曲线')
  4. 层级关系Figure 包含多个 AxesAxes 包含多个 primitive,修改父容器会影响子元素,比如修改 Figure 大小会自动调整所有 Axes 的布局。

2.属性调用方式

(1)属性的读写方式

Matplotlib 中所有 Artist 对象(线条、文字、画布、坐标轴等)的属性,都遵循统一的读写规范:

(a) 单属性读写:get_* / set_* 方法
  • 读取属性 :用 对象.get_属性名() 方法获取当前值

  • 修改属性 :用 对象.set_属性名(新值) 方法修改属性

  • 示例(透明度减半):

    复制代码
    a = o.get_alpha()  # 读取当前透明度
    o.set_alpha(0.5 * a)  # 将透明度设为原来的一半
(b)多属性批量设置:set() 方法

如果需要一次性修改多个属性,直接用 对象.set() 方法,以关键字参数传入,代码更简洁:

复制代码
# 同时设置透明度alpha和图层顺序zorder
o.set(alpha=0.5, zorder=2)
(c)通用属性查询:matplotlib.artist.getp()

这是 Matplotlib 提供的通用属性查看工具

  • 语法:matplotlib.artist.getp(对象, 属性名)

  • 用法 1:指定属性名 → 返回该属性的当前值

    复制代码
    import matplotlib
    matplotlib.artist.getp(o, "alpha")  # 获取o对象的alpha属性
  • 用法 2:不指定属性名 → 打印该对象的所有属性 + 当前值 ,是调试、查属性的神器

    复制代码
    # 查看Figure背景框(fig.patch)的所有属性
    matplotlib.artist.getp(fig.patch)

(2)fig.patch 全属性清单

(a)外观样式类
属性名 别名 作用 示例值
facecolor fc 填充色(背景色) (1.0, 1.0, 1.0, 0.0)(默认透明白)
edgecolor ec 边框颜色 (1.0, 1.0, 1.0, 0.0)(默认透明)
linewidth lw 边框线宽 0.0(默认无边框)
linestyle ls 边框线型 solid(实线)
alpha - 透明度 None(默认继承)
antialiased aa 抗锯齿 False(默认关闭)
(b) 几何与位置类
属性名 作用
bbox / extents / window_extent 图形的边界框,定义位置和大小
x / y / xy 矩形的左下角坐标
width / height 矩形的宽高(默认 1,相对画布比例)
verts 矩形的顶点坐标数组
(c)控制与交互类
属性名 作用
visible 控制元素是否显示(True/False
zorder 图层顺序,值越大越在顶层
picker 开启 / 设置元素的点击拾取交互
clip_on / clip_path 控制元素是否被裁剪、裁剪路径
animated 用于动画,控制元素是否参与动画更新
(d) 其他辅助类
  • label:元素的文本标签,用于图例

  • gid:图形 ID,用于 SVG/PDF 导出时的元素定位

  • url:为元素添加超链接(导出为 HTML/SVG 时生效)

  • hatch:填充图案(如///xxx

  • capstyle / joinstyle:线条端点、拐角的样式

    import matplotlib.pyplot as plt
    import matplotlib
    import numpy as np

    1. 创建画布和坐标轴

    fig = plt.figure(figsize=(6, 4))
    ax = fig.add_subplot(111)

    2. 绘制正弦曲线(Line2D对象,属于Artist)

    t = np.arange(0.0, 1.0, 0.01)
    s = np.sin(2 * np.pi * t)
    line, = ax.plot(t, s, color='blue', lw=2)

    ------------------- 单属性读写 -------------------

    读取当前线宽

    current_lw = line.get_linewidth()
    print(f"当前线宽: {current_lw}")

    将线宽翻倍

    line.set_linewidth(current_lw * 2)

    ------------------- 多属性批量设置 -------------------

    同时修改线条颜色、透明度、标签

    line.set(color='red', alpha=0.8, label='正弦曲线')

    ------------------- 查看Figure背景属性 -------------------

    print("\n=== Figure背景(fig.patch)的所有属性 ===")
    matplotlib.artist.getp(fig.patch)

    ------------------- 修改Figure背景样式 -------------------

    fig.patch.set(facecolor='#f0f0f0', # 浅灰色背景
    edgecolor='black', # 黑色边框
    linewidth=2, # 边框线宽2
    alpha=0.9) # 透明度0.9

    添加图例

    ax.legend()
    plt.show()

三.基本元素 - primitives

1.Line2D

(1)定义

  • Line2D 是 Matplotlib 中绘制 2D 曲线的核心类,路径为 matplotlib.lines.Line2D,基类是 matplotlib.artist.Artist,因此完全继承了 Artist 的属性读写规则。
  • 线条的含义:不仅是连接顶点的实线,还可以是虚线、顶点标记,受绘图风格完全控制。

(2)构造函数与常用参数

复制代码
class matplotlib.lines.Line2D(xdata, ydata, linewidth=None, linestyle=None, color=None, marker=None, markersize=None, ...)
参数 作用
xdata 线条点的 x 轴取值,省略则默认 range(1, len(ydata)+1)
ydata 线条点的 y 轴取值
linewidth/lw 线条宽度
linestyle/ls 线型(实线-、虚线--等)
color/c 线条颜色
marker 顶点标记样式(如os
markersize/ms 标记大小

(3)设置Line2D 属性

(a)直接在 plot() 函数中设置

适合快速绘图,一次性配置样式:

复制代码
import matplotlib.pyplot as plt
x = range(0,5)
y = [2,5,7,8,10]
plt.plot(x,y, linewidth=10)  # 直接设置线宽为10
plt.show()

接收 plot() 返回值的正确姿势

plt.plot() 返回的是列表 ,不是单个 Line2D 对象,因此必须用 line, = plt.plot(...)(加逗号)来解包,否则后续调用 set_* 会报错。

(b)获取线对象后单独设置

适合精细化调整,拿到 Line2D 实例后用 set_* 方法修改:

复制代码
x = range(0,5)
y = [2,5,7,8,10]
line, = plt.plot(x, y, '-')  # 注意逗号,plot返回列表,取第一个元素
line.set_antialiased(False)  # 关闭抗锯齿
plt.show()
(c)用 plt.setp() 批量设置

适合同时修改多个属性,代码更简洁:

复制代码
x = range(0,5)
y = [2,5,7,8,10]
lines = plt.plot(x, y)
plt.setp(lines, color='r', linewidth=10)  # 同时设置颜色和线宽
plt.show()

(4)Line2D 的绘制方式

(a)pyplot 快捷方法

直接用 plt.plot() 快速生成线条,自动创建画布和坐标轴:

复制代码
import matplotlib.pyplot as plt
x = range(0,5)
y = [2,5,7,8,10]
plt.plot(x,y)
plt.show()
(b)面向对象式(Line2D 实例手动添加)

适合复杂图表定制,手动创建 Line2D 对象并添加到 Axes

复制代码
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D

fig = plt.figure()
ax = fig.add_subplot(111)
line = Line2D(x, y)
ax.add_line(line)
# 手动设置坐标轴范围,否则不会自动适配
ax.set_xlim(min(x), max(x))
ax.set_ylim(min(y), max(y))
plt.show()

注:手动创建 Line2Dadd_line() 后,不会自动适配坐标轴范围 ,必须手动调用 ax.set_xlim()/ax.set_ylim(),否则线条会超出画布不可见。

(c)误差折线图:errorbar

errorbar 是专门用于绘制带误差线的折线图的工具,核心构造函数:

复制代码
matplotlib.pyplot.errorbar(x, y, yerr=None, xerr=None, fmt='', ecolor=None, elinewidth=None, capsize=None, ...)
参数 作用
x/y 折线的 x/y 轴数据
yerr y 轴方向的误差值
xerr x 轴方向的误差值
fmt 线条 + 标记样式(如co--表示青色圆圈标记 + 虚线)
ecolor 误差线的颜色
elinewidth 误差线的宽度
capsize 误差线末端横线的大小
复制代码
import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
x = np.arange(10)
y = 2.5 * np.sin(x / 20 * np.pi)
yerr = np.linspace(0.05, 0.2, 10)  # 生成递增的y轴误差
plt.errorbar(x, y + 3, yerr=yerr, label='both limits (default)')
plt.legend()
plt.show()
  • 可以通过 uplims/lolims 只显示单侧误差线
  • errorevery 控制误差线的显示频率,避免密集数据的误差线重叠
  • 支持自定义误差线样式、标记样式,完全兼容 Line2D 的属性

2.patches

Patch 基类:所有二维图形的父类

matplotlib.patches.Patch 是所有二维图形(矩形、多边形、楔形等)的基类,继承自 matplotlib.artist.Artist,统一了图形的样式属性。

复制代码
Patch(
    edgecolor=None,  # 边框颜色
    facecolor=None,  # 填充颜色
    color=None,      # 同时设置边框+填充色(优先级更高)
    linewidth=None,  # 边框宽度
    linestyle=None,  # 边框线型(实线/虚线等)
    antialiased=None,# 抗锯齿
    hatch=None,      # 填充纹理(如'/'、'x')
    fill=True,       # 是否填充
    capstyle=None,   # 端点样式
    joinstyle=None,  # 拐角样式
    **kwargs
)

所有子类(Rectangle、Polygon、Wedge)都继承了这些样式参数。

(1) Rectangle 矩形类

矩形是最常用的二维图形,直方图、柱状图本质都是由多个矩形组成。

构造函数

复制代码
class matplotlib.patches.Rectangle(
    xy,          # 矩形左下角锚点坐标 (x, y)
    width,       # 矩形宽度(x轴方向长度)
    height,      # 矩形高度(y轴方向长度)
    angle=0.0,   # 旋转角度(单位:度)
    **kwargs     # 继承Patch的样式参数
)
(a)基于 Rectangle 实现:hist 直方图

直方图用于统计数据在不同区间的分布,plt.hist 是封装好的快捷方法,底层由多个 Rectangle 组成。

核心参数

参数 作用
x 待统计的数据集
bins 统计的区间分布(整数 / 区间列表)
range 显示的区间(未指定 bins 时生效)
density True 显示频率统计,False 显示频数统计(替代旧版normed
histtype 直方图样式:bar(默认柱状)、step(梯状)、stepfilled(填充梯状)
align 柱子水平对齐方式:mid(居中,默认)、left/right
log True 启用 y 轴对数刻度
stacked True 绘制堆积直方图
alpha 透明度(0 完全透明,1 不透明)
复制代码
import matplotlib.pyplot as plt
import numpy as np

# 生成0-100之间的100个随机整数作为数据集
x = np.random.randint(0, 100, 100)
# 设置区间边界:[0,10), [10,20), ..., [90,100]
bins = np.arange(0, 101, 10)

# 绘制直方图:品红色,透明度0.5
plt.hist(x, bins, color='fuchsia', alpha=0.5)
plt.xlabel('scores')
plt.ylabel('count')
plt.xlim(0, 100)  # 限定x轴范围
plt.show()

底层实现:用 Rectangle 手动绘制直方图

通过 pandas 分箱统计后,用循环逐个添加矩形,完全复现直方图效果:

复制代码
import pandas as pd
import re
import matplotlib.pyplot as plt
import numpy as np

# 复用上面的x和bins
x = np.random.randint(0, 100, 100)
bins = np.arange(0, 101, 10)

# 1. 用pandas分箱统计
df = pd.DataFrame(columns=['data'])
df.loc[:, 'data'] = x
df['fenzu'] = pd.cut(df['data'], bins=bins, right=False, include_lowest=True)
df_cnt = df['fenzu'].value_counts().reset_index()

# 2. 提取每个区间的左右边界、宽度、频数
df_cnt.loc[:, 'mini'] = df_cnt['index'].astype(str).map(lambda x:re.findall('\[(.*)\,',x)[0]).astype(int)
df_cnt.loc[:, 'maxi'] = df_cnt['index'].astype(str).map(lambda x:re.findall('\,(.*)\)',x)[0]).astype(int)
df_cnt.loc[:, 'width'] = df_cnt['maxi'] - df_cnt['mini']
df_cnt.sort_values('mini', ascending=True, inplace=True)
df_cnt.reset_index(inplace=True, drop=True)

# 3. 用Rectangle逐个绘制柱子
fig = plt.figure()
ax1 = fig.add_subplot(111)

for i in df_cnt.index:
    # 锚点(区间左边界, 0),宽度=区间宽度,高度=该区间频数
    rect = plt.Rectangle(
        (df_cnt.loc[i, 'mini'], 0),
        df_cnt.loc[i, 'width'],
        df_cnt.loc[i, 'fenzu']
    )
    ax1.add_patch(rect)

ax1.set_xlim(0, 100)
ax1.set_ylim(0, 16)
plt.show()
(b)基于 Rectangle 实现:bar 柱状图

柱状图用于对比不同类别数据的大小,同样由多个矩形组成。

核心参数

参数 作用
left x 轴位置序列(柱子左下角 x 坐标)
height y 轴数值序列(柱子高度)
alpha 透明度
width 柱子宽度(默认 0.8)
color/facecolor 填充颜色
edgecolor 边框颜色
label 图例标签
lw 边框宽度
复制代码
import matplotlib.pyplot as plt
import numpy as np

y = range(1, 17)  # 柱子高度1-16
# 绘制柱状图:黄色填充、红色边框、宽度0.5、透明度0.5
plt.bar(
    np.arange(16), y,
    alpha=0.5, width=0.5,
    color='yellow', edgecolor='red',
    label='The First Bar', lw=3
)
plt.legend()
plt.ylim(0, 16)
plt.show()

底层实现:用 Rectangle 手动绘制柱状图

复制代码
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111)

for i in range(1, 17):
    # 锚点(i+0.25, 0):让柱子居中,宽度0.5,高度i
    rect = plt.Rectangle((i+0.25, 0), 0.5, i)
    ax1.add_patch(rect)

ax1.set_xlim(0, 16)
ax1.set_ylim(0, 16)
plt.show()

(2) Polygon 多边形类

用于绘制任意形状的闭合多边形,plt.fill 是其封装的快捷方法,常用于填充曲线下面积。

复制代码
class matplotlib.patches.Polygon(
    xy,          # N×2的numpy数组,存储多边形的所有顶点坐标
    closed=True, # True:自动闭合(起点=终点)
    **kwargs     # 继承Patch的样式参数
)
plt.fill 快捷绘制(填充曲线下面积)
复制代码
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 5 * np.pi, 1000)
y1 = np.sin(x)

# 填充sin(x)曲线与x轴之间的区域:绿色,透明度0.3
plt.fill(x, y1, color="g", alpha=0.3)
plt.ylim(-1, 1)
plt.show()

(3)Wedge 楔形类

楔形是 "扇形 / 圆环扇区",饼图的本质就是多个楔形的组合。

复制代码
class matplotlib.patches.Wedge(
    center,     # 楔形中心坐标 (x, y)
    r,          # 外圆半径
    theta1,     # 起始角度(单位:度,0°为x轴正方向,逆时针为正)
    theta2,     # 结束角度
    width=None, # 圆环宽度(None为实心扇形,否则为圆环扇区)
    **kwargs    # 继承Patch的样式参数
)
基于 Wedge 实现:pie 饼图

饼图用于展示各部分占整体的比例,plt.pie 是封装好的快捷方法。

核心参数

参数 作用
x 各部分数值(一维数组)
explode 各部分偏移量(数组,如[0,0.1,0,0]让第二个部分突出)
labels 各部分标签(列表)
colors 各部分颜色序列
autopct 百分比显示格式(如%1.1f%%
startangle 饼图起始角度(默认 0°,从 x 轴正方向开始)
shadow True 显示阴影
radius 饼图半径(默认 1)
复制代码
import matplotlib.pyplot as plt

labels = ['Frogs', 'Hogs', 'Dogs', 'Logs']
sizes = [15, 30, 45, 10]  # 各部分数值
explode = (0, 0.1, 0, 0.2)  # 突出Hogs部分

fig1, ax1 = plt.subplots()
# 绘制饼图:显示百分比、阴影、起始角度90°
ax1.pie(
    sizes, explode=explode, labels=labels,
    autopct='%1.1f%%', shadow=True, startangle=90
)
ax1.axis('equal')  # 保证饼图为正圆形
plt.show()

底层实现:用 Wedge 手动绘制饼图 / 圆环

复制代码
import matplotlib.pyplot as plt
from matplotlib.patches import Circle, Wedge
from matplotlib.collections import PatchCollection
import numpy as np

fig = plt.figure()
ax1 = fig.add_subplot(111)

# 定义4个楔形:实心圆、圆环、实心扇形、圆环扇区
patches = [
    Wedge((0.3, 0.3), .2, 0, 54),          # 实心扇形(0°-54°)
    Wedge((0.3, 0.3), .2, 54, 162),        # 实心扇形(54°-162°)
    Wedge((0.3, 0.3), .2, 162, 324),       # 实心扇形(162°-324°)
    Wedge((0.3, 0.3), .2, 324, 360, width=0.05) # 圆环扇区
]

# 批量添加楔形,设置透明度
colors = 100 * np.random.rand(len(patches))
p = PatchCollection(patches, alpha=0.4)
p.set_array(colors)
ax1.add_collection(p)

ax1.set_xlim(0, 0.6)
ax1.set_ylim(0, 0.6)
plt.show()
  1. Rectangle 锚点是左下角xy参数是矩形左下角坐标,不是中心,手动绘制时注意坐标计算。
  2. Wedge 角度单位是度theta1/theta2是角度,不是弧度,0° 为 x 轴正方向,逆时针递增。
  3. 饼图必须加ax1.axis('equal'):否则会被拉伸成椭圆。
  4. density替代normed :直方图中normed已废弃,官方推荐用density参数。

3.collections

collections 模块用于批量绘制一组同类型图形对象 ,可以统一管理样式、颜色、大小,大幅提升绘图效率,常见子类包括 RegularPolyCollectionCircleCollectionPathCollection 等,其中最常用的是散点图(scatter,基于 PathCollection 封装)。

scatter 散点图:PathCollection 的封装

Axes.scatter 是绘制散点图的核心方法,支持按数据动态调整点的大小、颜色,是数据分析中最常用的图表之一。

复制代码
Axes.scatter(
    self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
    vmin=None, vmax=None, alpha=None, linewidths=None, verts=,
    edgecolors=None, plotnonfinite=False, data=None, *kwargs
)

核心参数

参数 作用
x 数据点的 x 轴坐标序列
y 数据点的 y 轴坐标序列
s 点的大小(可传入数组,实现不同点大小不同)
c 点的颜色(可传入单个颜色,或数组映射颜色映射)
marker 标记的形状(如'o'圆形、's'方形、'^'三角形等)
cmap 颜色映射表(当c为数值数组时生效,如'viridis'
alpha 透明度(0 完全透明,1 不透明)
linewidths 标记边框宽度
edgecolors 标记边框颜色
复制代码
import matplotlib.pyplot as plt

# 定义数据
x = [0,2,4,6,8,10]
y = [10]*len(x)  # y轴统一为10,实现水平排列
# 点的大小按2的n次方递增,实现从左到右逐渐变大
s = [20*2**n for n in range(len(x))]

# 绘制散点图
plt.scatter(x,y,s=s)
plt.show()

效果:

6 个水平排列的圆点,从左到右尺寸依次翻倍,直观展示s参数对大小的控制。

4. images:图像绘制类

images 模块用于将二维数组渲染为图像 ,核心方法是 imshow,是可视化矩阵、热力图、图片的核心工具。

(1)imshow 核心方法

复制代码
# 底层类
class matplotlib.image.AxesImage(
    ax, cmap=None, norm=None, interpolation=None, origin=None,
    extent=None, filternorm=True, filterrad=4.0, resample=False, **kwargs
)

# 快捷绘图方法
matplotlib.pyplot.imshow(
    X, cmap=None, norm=None, aspect=None, interpolation=None, alpha=None,
    vmin=None, vmax=None, origin=None, extent=None, shape=, filternorm=1,
    filterrad=4.0, imlim=, resample=None, url=None, data=None, *kwargs
)

核心参数

参数 作用
X 输入的二维 / 三维数组(二维对应灰度图,三维对应 RGB 图像)
cmap 颜色映射表(灰度图常用'gray',热力图常用'viridis'/'hot'
interpolation 插值方法(控制图像放大 / 缩小时的平滑效果,核心重点)
origin 坐标原点位置('upper'默认,数组 [0,0] 在左上角;'lower'在左下角)
extent 图像的坐标范围([left, right, bottom, top],用于自定义坐标轴)
vmin/vmax 颜色映射的数值范围(超出部分按边界色显示)
alpha 图像透明度

(2)interpolation 插值方法全对比

插值是 imshow 最关键的参数之一,决定了低分辨率数组放大后的视觉效果,资料中展示了全部常用方法的效果:

复制代码
import matplotlib.pyplot as plt
import numpy as np

# 全部插值方法列表
methods = [None, 'none', 'nearest', 'bilinear', 'bicubic', 'spline16',
           'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric',
           'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos']

# 生成4x4随机数组(低分辨率测试数据)
grid = np.random.rand(4, 4)

# 创建3行6列子图,隐藏坐标轴
fig, axs = plt.subplots(nrows=3, ncols=6, figsize=(9, 6),
                        subplot_kw={'xticks': [], 'yticks': []})

# 遍历所有插值方法,绘制对比图
for ax, interp_method in zip(axs.flat, methods):
    ax.imshow(grid, interpolation=interp_method, cmap='viridis')
    ax.set_title(str(interp_method))

plt.tight_layout()
plt.show()

(3)插值方法分类

类别 代表方法 特点 适用场景
无插值(像素块) None/'none'/'nearest' 完全保留原始像素,无平滑,边缘锐利 展示原始数据、像素级标注、热力图
线性插值(快速平滑) 'bilinear' 双线性插值,计算快,平滑自然 通用场景、快速预览
高阶插值(高质量平滑) 'bicubic'/'spline16'/'spline36'/'lanczos' 高阶多项式插值,细节丰富,边缘清晰 高质量图像渲染、出版级图表
窗函数插值 'hanning'/'hamming'/'kaiser' 基于窗函数的插值,抑制振铃效应 信号处理、频谱图
高斯 / 贝塞尔插值 'gaussian'/'bessel' 基于高斯 / 贝塞尔函数的平滑,模糊效果强 降噪、模糊化展示

(4)collections 其他常用子类

除了PathCollection(散点图),collections还有两个高频子类:

  • CircleCollection :批量绘制一组圆形,统一设置大小、颜色,比循环add_patch效率高 10 倍以上
  • RegularPolyCollection:批量绘制正多边形,支持自定义边数、旋转角度
  1. scatters参数是面积,不是半径s的单位是点的面积(平方磅) ,不是直径 / 半径,因此点的视觉大小与s成正比,不是与√s 成正比。
  2. imshoworigin默认是upper :数组[0,0]对应图像左上角,若要匹配数学坐标系(原点在左下角),需手动设置origin='lower'
  3. 插值方法选型
    • 追求速度 / 原始像素:选nearest
    • 追求美观 / 出版级:选lanczos/bicubic
    • 通用场景:选bilinear(平衡速度与效果)
  4. cmap的使用 :灰度图必须指定cmap='gray',否则会用默认彩色映射;热力图推荐用'viridis'(色盲友好)。

四.对象容器- Object Container

容器(Container)是 Matplotlib 中用于 ** 管理一组基础图形元素(primitives)** 的对象,它不仅包含子元素,还拥有自身的属性,用于控制全局样式、坐标、布局等。

  • 典型例子:Axes 容器包含 Line2DText 等基础元素,同时拥有 xscale 属性,用于控制 X 轴是线性(linear)还是对数(log)刻度。

1. Figure 容器:最顶层容器

matplotlib.figure.Figure 是 Matplotlib 中最顶层的容器,包含了图表的所有元素,是整个画布的载体。

核心特性

  1. 背景元素 :图表的背景是 Figure.patch,本质是一个 Rectangle 矩形对象。

  2. Axes 管理 :通过 Figure.add_subplot()Figure.add_axes() 添加的子图,都会被自动存入 Figure.axes 列表中。

  3. :禁止手动修改 Figure.axes 列表,必须通过 add_subplot()/add_axes() 添加,delaxes() 删除;仅可遍历访问并修改 Axes 属性。

    import matplotlib.pyplot as plt

    创建Figure画布

    fig = plt.figure()

    添加2行1列的第1个子图

    ax1 = fig.add_subplot(211)

    添加自定义位置的Axes:(left, bottom, width, height),相对Figure的0-1坐标

    ax2 = fig.add_axes([0.1, 0.1, 0.7, 0.3])

    打印Axes实例

    print(ax1)

    打印Figure的axes列表,包含两个实例

    print(fig.axes)

    遍历所有Axes,统一添加网格线

    for ax in fig.axes:
    ax.grid(True)

    plt.show()

核心属性

属性 说明
Figure.patch Figure 的背景矩形,可修改背景色、边框等
Figure.axes 所有 Axes/Subplot 实例的列表
Figure.images FigureImage 图形元素列表
Figure.lines Line2D 线条元素列表(极少使用)
Figure.legends Figure 级别的图例列表(区别于 Axes 图例)
Figure.texts Figure 级别的文本元素列表

坐标系说明

Figure 默认使用像素坐标系 ,绘图时通常需要转换为 Figure 相对坐标系(0,0) 表示画布左下角,(1,1) 表示右上角。

2. Axes 容器:绘图的核心容器

matplotlib.axes.Axes 是 Matplotlib 最核心的容器 ,是我们实际绘图的区域,所有常见的绘图方法(plot()hist()imshow() 等)都基于 Axes 实现。

核心特性

  1. 背景元素 :Axes 包含 patch 属性:

    • 笛卡尔坐标系:patchRectangle 矩形,决定绘图区域的形状、背景色、边框。
    • 极坐标系:patchCircle 圆形。
  2. Subplot 本质Subplot 是特殊的 Axes,位于网格布局中;也可通过 add_axes() 在任意位置创建自定义 Axes。

  3. 元素管理 :禁止直接通过 Axes.lines/Axes.patches 列表添加元素,必须通过 add_line()/add_patch() 方法,Axes 会自动完成坐标转换、数据范围更新等自动化工作。

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib

    创建Figure和Axes

    fig = plt.figure()
    ax = fig.add_subplot(111)

    Axes的patch是Rectangle实例,修改背景色为绿色

    rect = ax.patch
    rect.set_facecolor('green')

    plt.show()

核心属性

属性 说明
artists 所有 Artist 实例的列表
patch Axes 绘图区域的矩形 / 圆形实例
collections Collection 集合元素列表(如散点图)
images Axes 图像元素列表(如 imshow 生成的图像)
legends Axes 级别的图例实例
lines Line2D 线条元素列表(如 plot 生成的曲线)
patches Patch 图形元素列表(如矩形、多边形)
texts Axes 级别的文本元素列表
xaxis XAxis 实例,管理 X 轴刻度、标签
yaxis YAxis 实例,管理 Y 轴刻度、标签

Matplotlib 容器层级关系

复制代码
Figure(顶层画布)
├─ Axes/Subplot(绘图区域,核心容器)
│  ├─ xaxis / yaxis(坐标轴容器,管理刻度、标签)
│  ├─ lines(Line2D 线条)
│  ├─ patches(矩形、多边形等图形)
│  ├─ collections(散点图等集合元素)
│  ├─ images(图像元素)
│  ├─ texts(文本元素)
│  └─ legends(图例元素)
├─ Figure.patch(画布背景)
├─ Figure.images(画布级图像)
├─ Figure.lines(画布级线条)
├─ Figure.legends(画布级图例)
└─ Figure.texts(画布级文本)
  1. 禁止手动修改容器列表Figure.axesAxes.linesAxes.patches 等列表由 Matplotlib 自动维护,手动增删会导致状态异常,必须通过官方方法操作。
  2. 优先使用 Axes 方法绘图 :所有绘图操作优先通过 ax.plot()ax.scatter() 等 Axes 方法实现,而非 plt.plot() 全局方法,避免多子图场景下的坐标混乱。
  3. 层级化样式修改
    • 全局画布样式:修改 Figure 属性
    • 绘图区域样式:修改 Axes 属性
    • 坐标轴样式:修改 xaxis/yaxis 属性
    • 单个元素样式:修改对应 Line2D/Patch 等元素的属性
  4. 坐标系统一:Figure 使用相对坐标(0-1),Axes 使用数据坐标,跨层级操作时注意坐标转换。

3. Axis 容器:坐标轴的核心管理者

matplotlib.axis.Axis 是 Axes 的子容器,专门负责坐标轴相关元素的绘制与管理,是自定义坐标轴样式的核心入口。

(1)核心作用

Axis 容器管理坐标轴的所有视觉元素:

  • 刻度线(tick line)、刻度标签(tick label)
  • 坐标网格线(grid line)、坐标轴标题(axis label)
  • 支持独立配置 X 轴上下侧、Y 轴左右侧的样式
  • 存储自适应缩放相关的 data_interval(数据范围)和 view_interval(视图范围)
  • 通过 Locator(刻度位置)和 Formatter(刻度格式)控制刻度的生成

(2)刻度分类

Axis 中的刻度分为两类,均为 Tick 对象:

  • 主刻度(major tick):默认显示的大刻度,带标签
  • 次刻度(minor tick):主刻度之间的细分刻度,默认无标签,用于辅助读数

(3)常用辅助方法

Axis 提供了一系列方法,用于获取和操作刻度元素:

方法 作用
axis.get_ticklocs() 获取刻度线的位置(数值数组)
axis.get_ticklabels(minor=False) 获取刻度标签(Text 实例列表,minor=True 可获取次刻度)
axis.get_ticklines(minor=False) 获取刻度线(Line2D 实例列表,minor=True 可获取次刻度)
axis.get_data_interval() 获取轴的数据范围(数据的真实区间)
axis.get_view_interval() 获取轴的视图范围(当前显示的区间)

(4)样式自定义示例

复制代码
import matplotlib.pyplot as plt

# 1. 创建画布与坐标轴
fig = plt.figure()
rect = fig.patch
rect.set_facecolor('lightgoldenrodyellow')  # 设置画布背景色

# 2. 创建自定义位置的Axes
ax1 = fig.add_axes([0.1, 0.3, 0.4, 0.4])
rect = ax1.patch
rect.set_facecolor('lightslategray')  # 设置Axes背景色

# 3. 自定义X轴刻度标签(Text实例)
for label in ax1.xaxis.get_ticklabels():
    label.set_color('red')        # 标签颜色
    label.set_rotation(45)        # 旋转45度
    label.set_fontsize(16)        # 字体大小

# 4. 自定义Y轴刻度线(Line2D实例)
for line in ax1.yaxis.get_ticklines():
    line.set_color('green')       # 刻度线颜色
    line.set_markersize(25)       # 刻度线长度
    line.set_markeredgewidth(2)   # 刻度线宽度

plt.show()

效果:

X 轴标签为红色、45° 旋转、大字体;Y 轴刻度线为绿色、加粗加长。

4. Tick 容器:最末端的刻度容器

matplotlib.axis.Tick 是 Matplotlib 容器层级的最末端对象 ,从 Figure → Axes → Axis → Tick 层层嵌套,每个刻度对应一个 Tick 实例。

(1)核心属性

每个 Tick 实例包含以下可操作的子元素:

属性 说明
Tick.tick1line Line2D 实例,主刻度线(Y 轴左侧 / X 轴下侧)
Tick.tick2line Line2D 实例,副刻度线(Y 轴右侧 / X 轴上侧)
Tick.gridline Line2D 实例,对应刻度的网格线
Tick.label1 Text 实例,主刻度标签(Y 轴左侧 / X 轴下侧)
Tick.label2 Text 实例,副刻度标签(Y 轴右侧 / X 轴上侧)

(2)刻度位置对应关系

  • Y 轴tick1 对应左侧,tick2 对应右侧
  • X 轴tick1 对应下侧,tick2 对应上侧

(3) 实战示例:Y 轴右侧显示美元格式标签

复制代码
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

# 1. 创建画布与数据
fig, ax = plt.subplots()
ax.plot(100*np.random.rand(20))  # 生成0-100的随机数据

# 2. 设置刻度格式:美元符号+两位小数
formatter = ticker.FormatStrFormatter('$%1.2f')
ax.yaxis.set_major_formatter(formatter)

# 3. 配置Y轴:右侧为主轴,标签绿色,隐藏左侧标签
ax.yaxis.set_tick_params(
    which='major',        # 仅作用于主刻度
    labelcolor='green',   # 标签颜色
    labelleft=False,      # 隐藏左侧标签
    labelright=True       # 显示右侧标签
)

plt.show()

效果:Y 轴刻度显示在右侧,格式为 $xx.xx,标签为绿色,完美适配金融数据可视化。

  1. 刻度是动态创建的 :只有在图表渲染时才会生成 Tick 实例,因此必须在 plt.show() 前操作,否则无法获取元素。
  2. 主次刻度区分 :所有刻度相关方法默认操作主刻度,需手动指定 minor=True 才能操作次刻度。
  3. 禁止手动修改容器列表Axis.get_ticklabels() 返回的是实例列表,禁止手动增删,仅可遍历修改属性。
  4. 坐标系统一:Axis 操作基于数据坐标,跨层级修改时注意坐标转换。

样式修改的正确层级

需求 操作层级 正确方法
修改画布背景 Figure fig.patch.set_facecolor()
修改绘图区背景 Axes ax.patch.set_facecolor()
修改坐标轴刻度标签 Axis ax.xaxis.get_ticklabels() 遍历修改
修改刻度线样式 Axis / Tick ax.yaxis.get_ticklines() 或直接操作 Tick 实例
修改刻度格式 Axis ax.yaxis.set_major_formatter()
切换刻度显示侧 Axis ax.yaxis.set_tick_params(labelleft=False, labelright=True)
相关推荐
MediaTea5 天前
人工智能通识课:Matplotlib 绘图基础
人工智能·matplotlib
MediaTea7 天前
Matplotlib 常用函数手册
matplotlib
badhope12 天前
Matplotlib实战30例:全类型图表代码库
人工智能·python·plotly·github·matplotlib
badhope12 天前
最小二乘与最速下降法实战解析
人工智能·机器学习·plotly·github·matplotlib
badhope12 天前
Docker入门到实战全攻略
linux·python·docker·github·matplotlib
李昊哲小课13 天前
matplotlib多子图与复杂布局实战
python·数据分析·matplotlib·数据可视化
李昊哲小课16 天前
matplotlib_tutorial
数据分析·matplotlib·数据可视化
byzh_rc17 天前
[AI工具从入门到入土] matplotlib
人工智能·matplotlib