跳至主要内容
课程笔记约 13 分钟

Matplotlib 实用教程

整理 Matplotlib 的基础绘图流程,以及图形配置、坐标轴、图例和布局工具的使用方式。

#Matplotlib#Python#数据可视化#绘图
本文目录
  1. 基础知识
  2. 配置界面
  3. 图形选项
  4. figure 的用法
  5. 设置坐标轴
  6. legend 图例设置
  7. annotation 标注设置
  8. scatter 散点图的用法
  9. bar 条形图的用法

基础知识

plt 是 matplotlib 库中 pyplot 的缩写。

plt.plot(x,y) 就是规定横纵轴的数:第一个参数是横坐标的值,第二个参数是纵坐标的值。

接下来介绍界面中各个按钮的用法。

Matplotlib 实用教程图示

配置界面

Matplotlib 实用教程图示

Borders(边界):这部分用于调整整个绘图区域(Figure)与子图(Axes)之间的空白边距。

  • top:顶部边距,控制子图顶部到绘图区域上边缘的距离
  • bottom:底部边距,控制子图底部到绘图区域下边缘的距离
  • left:左侧边距,控制子图左侧到绘图区域左边缘的距离
  • right:右侧边距,控制子图右侧到绘图区域右边缘的距离

Spacings(间距):这部分用于调整多个子图(subplots)之间的间距。

  • hspace:垂直间距(height space),控制上下排列的子图之间的垂直距离
  • wspace:水平间距(width space),控制左右排列的子图之间的水平距离

按钮功能

  • Tight layout:自动应用 “紧凑布局”,matplotlib 会自动调整子图和边距,避免标签、标题等元素重叠
  • Reset:将所有边距和间距重置为默认值
  • Export values:导出当前的布局参数(如 top=0.880hspace=0.200 等),方便在代码中复现这个布局
  • Close:关闭这个配置窗口

图形选项

Axes(坐标轴)标签页

Matplotlib 实用教程图示

这是当前激活的标签页,用于配置坐标轴和图表整体的基础属性:

  • Title:图表的主标题,输入文本后会显示在图表顶部。

X-Axis(X 轴)

  • Min / Max:设置 X 轴的显示范围(最小值和最大值),当前 X 轴范围约为 -0.051.05
  • Label:X 轴的标签文本,用于说明 X 轴代表的物理量或含义。
  • Scale:X 轴的刻度类型,可选 linear(线性)、log(对数)等,当前为线性刻度。

Y-Axis(Y 轴)

  • Min / Max:设置 Y 轴的显示范围,当前 Y 轴范围为 -1.11.1
  • Label:Y 轴的标签文本。
  • Scale:Y 轴的刻度类型,当前为线性刻度。

(Re-)Generate automatic legend:勾选后,matplotlib 会根据绘图数据自动生成图例,显示每条曲线的名称和样式。

曲线选择与标签

Matplotlib 实用教程图示

  • 下拉框(显示 _child0):用于选择当前要编辑的曲线,当图中有多条曲线时,可以在这里切换。
  • Label:曲线的名称,会显示在图例(legend)中,当前为 _child0,你可以修改为更有意义的名称,如 “训练集” 或 “预测值”。

Line(线条)设置

  • Line style:线条的样式,可选实线(Solid)、虚线(Dashed)、点线(Dotted)等,当前为实线。
  • Draw style:线条的绘制方式,如 Default、Steps-pre、Steps-post 等,控制数据点之间的连接方式。
  • Width:线条的宽度,当前为 1.5 像素。
  • Color (RGBA):线条的颜色,使用 RGBA 或十六进制格式表示,当前为 #1f77b4ff(一种蓝色),也可以点击右侧的颜色选择器来挑选。

Marker(数据标记点)设置

  • Style:数据点的标记形状,如圆形(o)、方形(s)、三角形(^)等,当前为 nothing,即不显示标记点。
  • Size:标记点的大小,当前为 6.0。
  • Face color (RGBA):标记点内部填充的颜色,当前与线条颜色一致。
  • Edge color (RGBA):标记点边缘的颜色,当前也与线条颜色一致。

按钮功能

  • OK:应用所有修改并关闭窗口。
  • Cancel:放弃所有修改并关闭窗口。
  • Apply:立即应用当前修改,但不关闭窗口,方便你实时预览效果。

figure 的用法

看完界面操作,回到代码本身:一切绘图都发生在画布(figure)上,先掌握它的用法。

常用的形式:

plt.figure(figsize=(10, 6), dpi=120),简洁且实用。

可传的参数:

plt.figure(
num="我的自定义画布",  # 画布标识(字符串)  
figsize=(8, 5),             # 尺寸     
dpi=150,                   # 分辨率     
facecolor="#f0f0f0",  # 背景色(十六进制)     
edgecolor="black",    # 边框色     
frameon=True           # 显示边框

然后要想一个图里出现多个曲线,就在一个 figure 下多整几个 plt.plot()

例如:

plt.figure()
plt.plot(x,y1)
plt.plot(x,y2)

关于 plt.plot,其是设置曲线的形态的,常用的形式:

plt.plot(x, y1, 'r--o', label='正弦曲线(快捷写法)', linewidth=1.5, markersize=8)

其中 'r--o' 是快捷样式符,代表红色 + 虚线 + 圆形标记。

可传参数为:

plt.plot(
    x, y2,
    color='#2ca02c',    # 绿色
    linestyle='-.',     # 点划线
    linewidth=2,        # 线宽
    marker='s',         # 方形标记
    markersize=6,       # 标记大小
    markerfacecolor='yellow',  # 标记填充色
    markeredgecolor='black',   # 标记边缘色
    alpha=0.8,          # 透明度
    label='余弦曲线(精细控制)'
)

设置坐标轴

画布和曲线都有了,接下来调整坐标轴的范围、刻度和样式,让图更易读。

  1. 常用操作如下:
plt.xlim(-1,2)     #设置x轴的上下限
plt.ylim(-2,5)     #设置y轴的上下限
plt.xlabel('x123') #设置x轴的标签
plt.ylabel('y123') #设置y轴的标签
  1. 设置刻度
new_ticks = np.linspace(-1,2,10)  
plt.xticks(new_ticks)  #设置x轴的刻度
plt.yticks([-2,0,2],[r'$bad$','normal','good']) #设置y的刻度——将对应的位置替换为对应的文字
  1. 设置坐标轴刻度样式(大小、颜色、方向)
plt.plot(x, y)
# 获取坐标轴对象(plt接口底层是Axes对象,更精细控制需要这个)
ax = plt.gca()  # gca = get current axes

# 设置X轴刻度字体大小、颜色
ax.tick_params(axis='x', labelsize=10, labelcolor='green')
# 设置Y轴刻度线大小、颜色,刻度朝内
ax.tick_params(axis='y', length=6, color='red', direction='in')
plt.show()
  1. 设置坐标轴类型
x = np.linspace(1, 100, 100)
y = x **2
plt.plot(x, y)

# X轴设为对数刻度,Y轴保持线性
plt.xscale('log')  # 可选:'linear'(默认)、'log''log2''log10'
# plt.yscale('log')  # Y轴对数刻度
plt.xlabel('对数刻度X轴')
plt.ylabel('线性刻度Y轴')
plt.show()
  1. 隐藏 / 显示坐标轴
plt.plot(x, y)
ax = plt.gca()

# 隐藏右侧和顶部的坐标轴
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)

# 隐藏X轴或Y轴(刻度和标签都隐藏)
# plt.xticks([])  # 隐藏X轴刻度和标签
# plt.yticks([])  # 隐藏Y轴刻度和标签
plt.show()
  1. 移动坐标轴(比如让坐标轴交叉在原点)
plt.plot(x - np.pi, y)  # 让曲线跨原点
ax = plt.gca()

# 移动X轴到y=0位置,移动Y轴到x=0位置
ax.spines['bottom'].set_position(('data', 0))  # X轴移到y=0
ax.spines['left'].set_position(('data', 0))    # Y轴移到x=0
plt.show()

legend 图例设置

图例的本质是将 plt.plot()中通过 label 参数定义的曲线名称,和对应的曲线样式(颜色、线型等)关联起来,显示在图表的指定位置。核心步骤分为两步:

  1. 绘图时给每条曲线指定 label 标签;

  2. 调用 plt.legend() 生成并显示图例。

  1. 最直接的用法:
# 1. 绘图时指定label(关键!没有label则图例无内容)
plt.plot(x, y1, color='#1f77b4', label='正弦曲线 sin(x)')
plt.plot(x, y2, color='#ff7f0e', label='余弦曲线 cos(x)')
# 2. 调用legend生成图例(默认位置:自动找最佳位置)
plt.legend()

plt.xlabel('弧度')
plt.ylabel('值')
plt.show()
  1. 美化图例样式参数:
plt.legend(
    loc='upper right',
    fontsize=10,        # 字体大小
    frameon=True,       # 显示边框(默认True)
    facecolor='#f0f0f0',# 背景色
    edgecolor='black',  # 边框颜色
    alpha=0.8,          # 整体透明度
    fancybox=True,      # 圆角边框
    shadow=True         # 阴影效果
)
  1. 手动指定图例内容(不依赖 plot 的 label):
# 绘图时不指定label
line1, = plt.plot(x, y1, color='#1f77b4')
line2, = plt.plot(x, y2, color='#ff7f0e')

# 手动指定图例:第一个参数是曲线对象,第二个是标签文字
plt.legend(
    [line1, line2],          # 要显示的曲线
    ['正弦', '余弦'],        # 对应的标签
    loc='lower center'
)
plt.show()
  1. 多列图例(适合多条曲线)
# 生成3条曲线
y3 = np.tan(x[:-1])  # 避开tan(π/2)的无穷值
plt.plot(x, y1, label='sin(x)')
plt.plot(x, y2, label='cos(x)')
plt.plot(x[:-1], y3, label='tan(x)')

# 图例显示为2列,减少纵向占用空间
plt.legend(ncol=2, loc='upper right', fontsize=9)
plt.show()
  1. 特殊场景:隐藏 / 显示部分图例
# 给不需要显示的曲线加label='_nolegend_'
plt.plot(x, y1, label='sin(x)')  # 显示在图例
plt.plot(x, y2, label='_nolegend_')  # 不显示在图例

plt.legend()
plt.show()

annotation 标注设置

图例解决的是“每条线是什么”,而标注解决的是“某个点为什么重要”。本节介绍 matplotlib 中 plt.annotate()(标注 / 注释)的使用方法,它可以在图表上给特定数据点添加文字说明、箭头指向等,让图表更易理解。

  1. 无箭头的简单注释
# 给正弦曲线最大值点加注释(无箭头)
plt.annotate(
    text='sin(x)最大值',  # 注释文字
    xy=(np.pi/2, 1),      # 被注释的点(π/2, 1)
    fontsize=11,          # 字体大小
    color='red',          # 文字颜色
    ha='left',            # 文字左对齐目标点
    va='bottom'           # 文字底部对齐目标点
)

plt.xlabel('弧度')
plt.ylabel('sin(x)')
plt.show()
  1. 带箭头的注释(最常用)
plt.plot(x, y, color='#1f77b4')
plt.xlim(0, 2*np.pi)
plt.ylim(-1.1, 1.1)

# 带箭头的注释:指向最大值点,文字在右侧
plt.annotate(
    text='最大值: 1',
    xy=(np.pi/2, 1),                # 箭头指向的点
    xytext=(np.pi/2 + 0.8, 0.8),    # 文字显示的位置
    arrowprops=dict(                # 箭头配置
        arrowstyle='->',            # 箭头样式(-> / <- / <-> 等)
        color='red',                # 箭头颜色
        linewidth=1.5,              # 箭头线宽
        connectionstyle='arc3,rad=0.2'  # 箭头弧线(可选)
    ),
    fontsize=11,
    ha='center',                    # 文字水平居中
    va='center',
    bbox=dict(                      # 给文字加背景框
        boxstyle='round,pad=0.3',   # 圆角框,内边距
        facecolor='yellow',         # 背景色
        alpha=0.7                   # 透明度
    )
)

# 再添加最小值注释
plt.annotate(
    text='最小值: -1',
    xy=(3*np.pi/2, -1),
    xytext=(3*np.pi/2 - 0.8, -0.8),
    arrowprops=dict(arrowstyle='->', color='green'),
    fontsize=11,
    bbox=dict(boxstyle='square,pad=0.3', facecolor='lightgreen', alpha=0.7)
)

plt.xlabel('弧度')
plt.ylabel('sin(x)')
plt.show()
  1. 注释数学公式(支持 LaTeX 语法)
plt.plot(x, y, color='#1f77b4')
plt.annotate(
    text=r'$\sin(\frac{\pi}{2}) = 1$',  # LaTeX公式(r表示原生字符串)
    xy=(np.pi/2, 1),
    xytext=(np.pi/2 + 0.5, 0.6),
    arrowprops=dict(arrowstyle='->', color='purple'),
    fontsize=12,
    color='purple'
)
plt.show()
  1. 批量注释多个点
# 生成数据点
x = np.linspace(0, 2*np.pi, 5)
y = np.sin(x)
plt.plot(x, y, 'o-', color='#1f77b4')

# 循环注释每个点
for xi, yi in zip(x, y):
    plt.annotate(
        text=f'({xi:.2f}, {yi:.2f})',  # 格式化显示坐标
        xy=(xi, yi),
        xytext=(xi + 0.1, yi + 0.1),
        fontsize=9,
        color='black'
    )

plt.xlim(-0.2, 2*np.pi + 0.2)
plt.ylim(-1.1, 1.1)
plt.show()

scatter 散点图的用法

前面的内容都围绕折线图展开,从这一节开始换图表类型。plt.scatter()(散点图)专门用于绘制离散的点集,相比 plt.plot() 更适合展示数据的分布、相关性等特征。

  1. 最简散点图(固定大小 / 颜色)
plt.figure(figsize=(8, 6), dpi=100)
# 绘制散点图:大小50,蓝色,黑色边缘,透明度0.7
plt.scatter(
    x, y,
    s=50,                # 点大小
    c='skyblue',         # 点颜色
    edgecolors='black',  # 边缘颜色
    linewidths=1,        # 边缘宽度
    alpha=0.7,           # 透明度
    label='随机数据点'
)

带 “大小 / 颜色维度” 的散点图(核心进阶用法)

sizes = np.random.rand(100) * 200  # 每个点大小不同(0-200)
colors = np.random.rand(100)       # 每个点颜色值不同(0-1)

plt.figure(figsize=(8, 6), dpi=100)
# 绘制带大小+颜色维度的散点图
scatter = plt.scatter(
    x, y,
    s=sizes,         # 大小映射
    c=colors,        # 颜色映射
    cmap='viridis',  # 颜色映射表(蓝到黄)
    edgecolors='gray',
    alpha=0.8,
    label='多维度数据点'
)

# 添加颜色条(解释颜色对应的数值)
plt.colorbar(scatter, label='颜色维度值')
  1. 多组数据的散点图

就是在一个 plt.figure 下整多个 plt.scatter

bar 条形图的用法

散点图看分布,柱状图看对比。plt.bar()(柱状图)专门用于展示分类数据的对比,能直观呈现不同类别下的数值大小。

  1. 最简柱状图(单组数据)
import matplotlib.pyplot as plt
import numpy as np

# 分类标签和对应数值
categories = ['产品A', '产品B', '产品C', '产品D']
values = [15, 28, 20, 12]

plt.figure(figsize=(8, 6), dpi=100)
# 绘制基础柱状图
plt.bar(
    x=categories,        # 分类标签
    height=values,       # 柱子高度
    width=0.6,           # 柱子宽度
    color='#1f77b4',     # 柱子颜色
    edgecolor='black',   # 边缘颜色
    linewidth=1,         # 边缘宽度
    alpha=0.8            # 透明度
)

# 基础配置:添加数值标签、标题、坐标轴
plt.title('不同产品销量对比', fontsize=14)
plt.xlabel('产品类别', fontsize=12)
plt.ylabel('销量(件)', fontsize=12)

# 给每个柱子顶部添加数值标签(关键技巧)
for i, v in enumerate(values):
    plt.text(i, v + 0.5, str(v), ha='center', va='bottom', fontsize=11)

plt.grid(axis='y', alpha=0.3)  # 仅显示y轴网格线
plt.show()
  1. 多组并列柱状图(核心进阶用法)
# 数据准备
categories = ['产品A', '产品B', '产品C', '产品D']
values_2023 = [15, 28, 20, 12]
values_2024 = [18, 25, 22, 15]

# 柱子位置:用np.arange确定基础位置,通过偏移实现并列
x = np.arange(len(categories))
width = 0.35  # 每组柱子的宽度(总和<1避免重叠)

plt.figure(figsize=(8, 6), dpi=100)
# 绘制2023年数据(左偏移)
plt.bar(x - width/2, values_2023, width, label='2023年', color='#1f77b4')
# 绘制2024年数据(右偏移)
plt.bar(x + width/2, values_2024, width, label='2024年', color='#ff7f0e')

# 配置标签和刻度
plt.title('2023-2024年产品销量对比', fontsize=14)
plt.xlabel('产品类别', fontsize=12)
plt.ylabel('销量(件)', fontsize=12)
plt.xticks(x, categories)  # 替换x轴刻度为分类标签
plt.legend()

# 添加数值标签
for i, (v1, v2) in enumerate(zip(values_2023, values_2024)):
    plt.text(i - width/2, v1 + 0.5, str(v1), ha='center', va='bottom')
    plt.text(i + width/2, v2 + 0.5, str(v2), ha='center', va='bottom')

plt.grid(axis='y', alpha=0.3)
plt.show()
  1. 堆叠柱状图
# 数据准备
categories = ['产品A', '产品B', '产品C', '产品D']
online = [8, 15, 10, 7]
offline = [7, 13, 10, 5]

plt.figure(figsize=(8, 6), dpi=100)
# 绘制底层(线下)
plt.bar(categories, offline, label='线下销量', color='#ff7f0e', width=0.6)
# 绘制上层(线上,bottom=offline表示从线下销量顶部开始)
plt.bar(categories, online, bottom=offline, label='线上销量', color='#1f77b4', width=0.6)

# 配置
plt.title('产品销量-线上/线下构成', fontsize=14)
plt.xlabel('产品类别', fontsize=12)
plt.ylabel('销量(件)', fontsize=12)
plt.legend()

# 添加数值标签(线下+线上)
for i, (o1, o2) in enumerate(zip(offline, online)):
    # 线下标签
    plt.text(i, o1/2, str(o1), ha='center', va='center', color='white', fontsize=11)
    # 线上标签
    plt.text(i, o1 + o2/2, str(o2), ha='center', va='center', color='white', fontsize=11)
    # 总计标签
    plt.text(i, o1 + o2 + 0.5, str(o1+o2), ha='center', va='bottom', fontsize=11)

plt.grid(axis='y', alpha=0.3)
plt.show()
  1. 水平柱状图
categories = ['超长名称的产品A', '超长名称的产品B', '超长名称的产品C']
values = [25, 32, 18]

plt.figure(figsize=(8, 6), dpi=100)
plt.barh(categories, values, color='#2ca02c', height=0.6)
plt.title('水平柱状图(长标签适配)', fontsize=14)
plt.xlabel('销量(件)', fontsize=12)
plt.ylabel('产品类别', fontsize=12)

# 添加数值标签
for i, v in enumerate(values):
    plt.text(v + 0.5, i, str(v), ha='left', va='center', fontsize=11)

plt.grid(axis='x', alpha=0.3)
plt.show()
  1. 自定义柱子颜色(渐变 / 指定颜色)
categories = ['A', 'B', 'C', 'D']
values = [15, 28, 20, 12]
# 给每个柱子指定不同颜色
colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']

plt.bar(categories, values, color=colors, width=0.6, edgecolor='black')
plt.title('自定义柱子颜色', fontsize=14)
plt.show()