第一部分:Matplotlib基础概念

1. Matplotlib简介

1.1 什么是Matplotlib?
Matplotlib 是 Python 中最流行的数据可视化库之一,由 John D. Hunter 于 2003 年创建。它的核心功能是通过编程生成静态、动态或交互式的图表,支持多种输出格式(如 PNG、PDF、SVG)。

  • 主要特点
    • 支持多种图表类型(折线图、散点图、柱状图、饼图等)。
    • 高度可定制化(颜色、标签、标题、网格、图例等)。
    • 与 NumPy、Pandas 无缝集成,适合科学计算和数据分析。
    • 提供面向对象和类 MATLAB 风格的两种编程接口。

1.2 核心组件
Matplotlib 的结构基于分层对象模型,关键组件包括:

  • Figure(画布)
    所有图表的顶层容器,可理解为一张空白画纸。通过 plt.figure() 创建。
    fig = plt.figure(figsize=(8, 4))  # 设置画布大小(宽8英寸,高4英寸)
    
  • Axes(坐标系)
    Figure 上创建的绘图区域,包含坐标轴、标签、数据图形等。一个 Figure 可以包含多个 Axes
    ax = fig.add_subplot(1, 1, 1)  # 在画布上添加一个子图
    
  • Axis(坐标轴)
    控制 Axes 的坐标轴范围、刻度、标签等。例如 ax.xaxis.set_ticks()
  • Artist(元素)
    所有可见元素的基类,包括文本、线条、矩形等。用户可通过 Artist 对象精细控制图表细节。

1.3 两种编程接口
Matplotlib 提供两种风格的 API,适应不同需求:

  • 面向对象(OO)风格
    显式创建 FigureAxes 对象,适合复杂图表和脚本编程。
    fig, ax = plt.subplots()  # 创建画布和坐标系
    ax.plot([1, 2, 3], [4, 5, 6])  # 在坐标系中绘图
    ax.set_xlabel("X Axis")        # 设置坐标轴标签
    
  • 类 MATLAB 风格
    使用 pyplot 模块的全局状态机接口,语法类似 MATLAB,适合快速绘图。
    plt.plot([1, 2, 3], [4, 5, 6])  # 直接绘图
    plt.xlabel("X Axis")            # 全局设置标签
    plt.show()                      # 显示图表
    
  • 对比与选择
    • OO 风格:推荐用于复杂图表、多子图布局或需要复用的代码。
    • MATLAB 风格:适合快速交互式绘图(如 Jupyter Notebook 中的简单可视化)。

1.4 与其他可视化库的对比

  • Seaborn
    • 基于 Matplotlib,提供更高级的统计图表接口(如热力图、分布图)。
    • 默认样式更美观,适合数据探索。
  • Plotly/Bokeh
    • 支持交互式图表(缩放、悬停提示),适合 Web 应用。
    • 语法与 Matplotlib 差异较大,学习曲线较陡。
  • Matplotlib 的定位
    • 灵活性强,但 API 较为底层,适合需要高度定制的场景。

2. 安装与环境配置

2.1 安装 Matplotlib

  • 通过 pip 安装
    pip install matplotlib
    
  • 通过 conda 安装
    conda install matplotlib
    
  • 验证安装
    import matplotlib
    print(matplotlib.__version__)  # 输出版本号,如 3.7.1
    

2.2 Jupyter Notebook 配置

  • 内嵌显示图表
    在 Notebook 单元格中运行以下代码,使图表直接嵌入输出区域:
    %matplotlib inline
    
  • 调整分辨率
    %config InlineBackend.figure_format = 'retina'  # 支持高分辨率显示
    

2.3 常见 IDE 支持

  • PyCharm
    • 需在代码末尾调用 plt.show() 以显示图表。
    • 配置科学模式(Scientific Mode)可实时预览图表。
  • VS Code
    • 安装 Python 扩展后,直接运行代码即可在窗口内显示图表。
    • 使用 # %% 分隔代码单元格,支持交互式绘图。

2.4 常见问题解决

  • 中文显示乱码
    需手动指定中文字体(如 SimHei、Microsoft YaHei):
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体
    plt.rcParams['axes.unicode_minus'] = False    # 解决负号显示异常
    
  • 图表不显示
    • 确保在脚本中调用 plt.show()
    • 在 Notebook 中检查是否运行了 %matplotlib inline

第二部分:基础绘图

1. 快速绘制第一张图

1.1 基本绘图流程
Matplotlib 最简单的绘图流程仅需 3 步:

  1. 导入库import matplotlib.pyplot as plt
  2. 绘制数据plt.plot([x数据], [y数据])
  3. 显示图表plt.show()

示例代码

import matplotlib.pyplot as plt

# 数据(省略x轴时,默认使用索引作为x值)
y = [2, 4, 1, 5]  
plt.plot(y)          # 绘制折线图
plt.ylabel("数值")   # 添加y轴标签
plt.title("简单折线图")  # 添加标题
plt.show()           # 显示图表

输出效果

  • 生成一条以索引 [0, 1, 2, 3] 为 x 轴,[2, 4, 1, 5] 为 y 轴的折线图。

2. 常用图表类型

Matplotlib 支持多种基础图表类型,以下是核心图表及其用法:

2.1 折线图 (plt.plot)

  • 功能:显示数据随时间或其他连续变量的变化趋势。
  • 关键参数
    • color:颜色(如 'r''#FF5733'
    • linestyle:线型(如 '--' 虚线、':' 点线)
    • marker:数据点标记(如 'o' 圆圈、's' 方块)
    • linewidth:线宽(如 2.0

示例:多线叠加折线图

import numpy as np

x = np.linspace(0, 2*np.pi, 50)
y1 = np.sin(x)
y2 = np.cos(x)

plt.plot(x, y1, color='blue', linestyle='-', label='sin(x)')
plt.plot(x, y2, color='red', linestyle='--', marker='o', label='cos(x)')
plt.xlabel("x 轴")
plt.ylabel("y 轴")
plt.legend()  # 显示图例
plt.grid(True)  # 显示网格
plt.show()

2.2 散点图 (plt.scatter)

  • 功能:展示两个变量之间的相关性或分布。
  • 关键参数
    • s:点的大小(标量或数组)
    • c:颜色(支持单色或颜色映射)
    • alpha:透明度(0~1)
    • cmap:颜色映射(如 'viridis'

示例:颜色映射散点图

x = np.random.randn(100)
y = np.random.randn(100)
colors = np.random.rand(100)  # 随机颜色值
sizes = 100 * np.random.rand(100)  # 随机大小

plt.scatter(x, y, c=colors, s=sizes, alpha=0.6, cmap='viridis')
plt.colorbar()  # 显示颜色条
plt.xlabel("X 变量")
plt.ylabel("Y 变量")
plt.title("散点图示例")
plt.show()

2.3 柱状图 (plt.bar)

  • 功能:比较不同类别的数值大小。
  • 关键参数
    • width:柱宽(默认 0.8)
    • align:对齐方式('center''edge'
    • edgecolor:边框颜色
    • hatch:填充图案(如 '//' 斜线)

示例:分组柱状图

labels = ['A', 'B', 'C', 'D']
values1 = [20, 35, 30, 25]
values2 = [15, 32, 34, 20]

x = np.arange(len(labels))  # 生成索引 [0,1,2,3]
width = 0.35  # 柱宽

plt.bar(x - width/2, values1, width, label='组1', edgecolor='black')
plt.bar(x + width/2, values2, width, label='组2', hatch='//')
plt.xticks(x, labels)  # 设置x轴刻度标签
plt.legend()
plt.title("分组柱状图")
plt.show()

2.4 饼图 (plt.pie)

  • 功能:显示各类别占比。
  • 关键参数
    • explode:突出显示某部分(如 [0.1, 0, 0, 0]
    • autopct:显示百分比格式(如 '%1.1f%%'
    • shadow:添加阴影
    • startangle:起始角度(0~360)

示例:带百分比和突出效果的饼图

sizes = [30, 25, 15, 20, 10]
labels = ['A', 'B', 'C', 'D', 'E']
explode = [0.1, 0, 0, 0, 0]  # 突出第一块

plt.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
        shadow=True, startangle=90)
plt.axis('equal')  # 保证饼图为正圆
plt.title("饼图示例")
plt.show()

2.5 直方图 (plt.hist)

  • 功能:展示数据分布和频次。
  • 关键参数
    • bins:分箱数量(决定柱的精细度)
    • range:数据范围(如 (0, 100)
    • density:是否显示概率密度(取代频次)
    • histtype:类型('bar', 'step', 'stepfilled'

示例:概率密度直方图

data = np.random.normal(0, 1, 1000)  # 生成正态分布数据

plt.hist(data, bins=30, density=True, alpha=0.7, edgecolor='black')
plt.xlabel("数值区间")
plt.ylabel("概率密度")
plt.title("正态分布直方图")
plt.show()

2.6 箱线图 (plt.boxplot)

  • 功能:展示数据分布的五数概括(最小值、第一四分位、中位数、第三四分位、最大值)及离群值。
  • 关键参数
    • notch:是否显示中位数的置信区间(凹口)
    • vert:方向(True 为垂直,False 为水平)
    • patch_artist:是否填充箱体颜色

示例:多组数据箱线图

data = [np.random.normal(0, 1, 100),
        np.random.normal(2, 1.5, 100),
        np.random.normal(-1, 0.5, 100)]

plt.boxplot(data, notch=True, patch_artist=True, labels=['组1', '组2', '组3'])
plt.ylabel("观测值")
plt.title("多组箱线图")
plt.grid(True, linestyle='--', alpha=0.5)
plt.show()

3. 图表元素定制

3.1 标题与坐标轴

  • 方法
    • plt.title("标题")
    • plt.xlabel("X 轴标签")
    • plt.ylabel("Y 轴标签")
  • 参数
    • fontsize:字体大小(如 14
    • color:颜色(如 '#333333'

示例

plt.plot([1, 2, 3], [4, 5, 1])
plt.title("自定义标题", fontsize=16, color='blue')
plt.xlabel("X 轴", fontsize=12, color='gray')
plt.ylabel("Y 轴", fontsize=12, color='gray')
plt.show()

3.2 坐标轴范围与刻度

  • 方法
    • plt.xlim(0, 10):设置 x 轴范围
    • plt.ylim(-5, 5):设置 y 轴范围
    • plt.xticks([0, 1, 2], ['A', 'B', 'C']):自定义刻度标签

示例

x = np.linspace(0, 2*np.pi, 100)
plt.plot(x, np.sin(x))
plt.xlim(0, 2*np.pi)  # 设置x轴范围
plt.xticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi],
          ['0', 'π/2', 'π', '3π/2', '2π'])  # 自定义刻度
plt.title("正弦波")
plt.show()

3.3 图例 (plt.legend)

  • 参数
    • loc:位置(如 'upper left''best'
    • ncol:列数(多列排列图例)
    • frameon:是否显示边框

示例:多列图例

x = np.linspace(0, 10, 100)
plt.plot(x, x**2, label='二次函数')
plt.plot(x, x**3, label='三次函数')
plt.legend(loc='upper center', ncol=2, frameon=False)
plt.show()

3.4 网格与注释

  • 网格plt.grid(True, linestyle='--', alpha=0.5)
  • 文本注释
    • plt.text(x, y, "文本"):在指定坐标添加文本
    • plt.annotate("注释", xy=(x,y), xytext=(tx,ty), arrowprops=dict(arrowstyle="->"))

示例:添加箭头注释

plt.plot([1, 2, 3], [4, 5, 1])
plt.annotate('峰值', xy=(2,5), xytext=(1,6),
            arrowprops=dict(facecolor='red', arrowstyle='->'))
plt.text(3, 1, '最低点', color='blue')
plt.grid(True, linestyle=':', alpha=0.7)
plt.show()

第三部分:高级绘图与布局

1. 多图布局

Matplotlib 支持在单张画布中创建多个子图,适用于对比分析或复杂数据展示。

1.1 使用 plt.subplots() 创建子图

  • 基本语法
    fig, axes = plt.subplots(nrows=行数, ncols=列数, figsize=(,))
    
    返回一个 Figure 对象和包含子图 Axes 对象的数组。

示例:2x2 子图布局

fig, axes = plt.subplots(2, 2, figsize=(10, 6))  # 2行2列
axes[0,0].plot([1, 2, 3], [1, 4, 9])  # 左上子图
axes[0,0].set_title("子图1")
axes[0,1].scatter(np.random.rand(10), np.random.rand(10))  # 右上子图
axes[1,0].bar(['A', 'B', 'C'], [3, 7, 2])  # 左下子图
axes[1,1].hist(np.random.randn(1000), bins=30)  # 右下子图
plt.tight_layout()  # 自动调整子图间距
plt.show()

1.2 使用 GridSpec 实现复杂布局

  • 功能:自由定义子图的位置和大小比例。
  • 示例:左侧大图 + 右侧两行小图
import matplotlib.gridspec as gridspec

fig = plt.figure(figsize=(10, 6))
gs = gridspec.GridSpec(2, 2, width_ratios=[3, 1], height_ratios=[1, 2])  # 定义网格比例

ax1 = fig.add_subplot(gs[:, 0])    # 左侧占所有行
ax2 = fig.add_subplot(gs[0, 1])    # 右上方
ax3 = fig.add_subplot(gs[1, 1])    # 右下方

ax1.plot(np.random.randn(100))     # 主图
ax2.pie([30, 70], labels=['A', 'B'])  # 右上饼图
ax3.barh(['X', 'Y'], [5, 3])       # 右下水平柱状图
plt.tight_layout()

1.3 共享坐标轴

  • 应用场景:多子图共享 x 轴或 y 轴,避免重复刻度。
  • 方法
    fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)  # 共享x轴
    ax1.plot(x, y1)
    ax2.plot(x, y2)
    

2. 样式与主题

2.1 预定义样式
Matplotlib 内置多种样式,一键切换全局风格:

plt.style.use('ggplot')  # 可选样式:'seaborn', 'dark_background', 'fivethirtyeight'等
  • 查看所有可用样式
    print(plt.style.available)
    

2.2 自定义全局配置 (rcParams)

  • 调整字体、颜色、线宽等全局参数
    plt.rcParams.update({
        'font.size': 12,          # 全局字体大小
        'axes.titlesize': 16,     # 标题字体大小
        'axes.labelsize': 14,     # 坐标轴标签大小
        'lines.linewidth': 2,     # 线宽
        'grid.color': '0.8',      # 网格颜色
    })
    

3. 颜色与标记

3.1 颜色映射 (Colormap)

  • 应用场景:在散点图、热力图中用颜色表示数据强度。
  • 示例:散点图颜色映射
x = np.random.rand(100)
y = np.random.rand(100)
colors = np.random.rand(100)  # 颜色值范围0~1

plt.scatter(x, y, c=colors, cmap='viridis')  # 使用'viridis'颜色映射
plt.colorbar(label='强度')  # 添加颜色条

3.2 自定义颜色列表

  • 直接指定颜色
    plt.plot(x, y, color='#FF5733')  # 十六进制颜色
    plt.bar(labels, values, color=['red', 'green', 'blue'])  # 不同柱子不同颜色
    

4. 高级图表

4.1 双纵坐标轴

  • 方法ax.twinx() 创建共享 x 轴的第二个 y 轴。
fig, ax1 = plt.subplots()

# 第一个y轴(左侧)
ax1.plot(x, y1, color='blue', label='温度')
ax1.set_ylabel('温度 (°C)')

# 第二个y轴(右侧)
ax2 = ax1.twinx()
ax2.plot(x, y2, color='red', label='湿度')
ax2.set_ylabel('湿度 (%)')

plt.title("双纵坐标轴示例")
fig.legend(loc='upper left')  # 合并图例
plt.show()

4.2 误差线 (plt.errorbar)

  • 功能:显示数据点的误差范围。
x = np.arange(5)
y = [2, 3, 1, 4, 2]
y_err = [0.3, 0.4, 0.2, 0.6, 0.1]

plt.errorbar(x, y, yerr=y_err, fmt='o', capsize=5, label='数据')
plt.xlabel("X轴")
plt.ylabel("Y轴")
plt.legend()
plt.show()

4.3 极坐标图

  • 方法:通过 projection='polar' 切换为极坐标系。
theta = np.linspace(0, 2*np.pi, 100)
r = np.sin(3*theta)  # 三叶玫瑰线

plt.subplot(111, projection='polar')  # 极坐标子图
plt.plot(theta, r)
plt.title("极坐标图示例")
plt.show()

4.4 3D 绘图

  • 步骤:导入 mplot3d 工具包,创建 3D 坐标系。
from mpl_toolkits import mplot3d

fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')  # 创建3D坐标系

# 生成数据
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))

# 绘制3D曲面
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
ax.set_zlabel('Z轴')
plt.title("3D曲面图")
plt.show()

5. 实战技巧

5.1 调整子图间距

  • 方法
    plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1, wspace=0.3, hspace=0.4)
    
    • wspace:水平间距
    • hspace:垂直间距

5.2 保存高清图表

  • 参数
    plt.savefig('output.png', dpi=300, bbox_inches='tight', transparent=True)
    
    • dpi:分辨率(每英寸点数)
    • bbox_inches:去除多余白边

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐