Matplotlib 教程

Matplotlib 教程

Matplotlib 是 Python 最流行的数据可视化库,能绘制从简单折线图到复杂 3D 图形的各种图表,是数据分析、科研与机器学习可视化的标配工具。

本教程包含

  • 基础篇:安装、Pyplot 基础、绘图标记、绘图线
  • 样式篇:轴标签与标题、网格线、多图、子图
  • 进阶篇:散点图、柱状图、饼图、直方图、箱线图
  • 应用篇:3D 图、图像、Matplotlib 集成、总结

特点

功能全面: 2D/3D 图表全覆盖
高度可定制: 颜色/字体/坐标轴/标注
多种输出: PNG/SVG/PDF/交互界面
与 NumPy/Pandas 无缝协作
Matlab 风格 API 与面向对象 API

安装

pip install matplotlib

Matplotlib 安装

Matplotlib 安装

安装 Matplotlib 并配置中文显示。

安装

# pip
pip install matplotlib

# conda
conda install matplotlib

# 验证
import matplotlib
print(matplotlib.__version__)

中文显示配置

import matplotlib.pyplot as plt

# 解决中文乱码
plt.rcParams["font.sans-serif"] = ["SimHei", "PingFang SC", "Microsoft YaHei"]
plt.rcParams["axes.unicode_minus"] = False   # 负号正常显示

# 查看可用字体
from matplotlib import font_manager
fonts = [f.name for f in font_manager.fontManager.ttflist]
print(fonts)

检查后端(显示方式)

# 交互环境(Jupyter): 默认 inline 显示
# 脚本: 保存图片
plt.savefig("chart.png", dpi=150)

# 查看后端
import matplotlib
print(matplotlib.get_backend())

快速上手

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8, 10]

plt.plot(x, y)
plt.title("简单折线图")
plt.show()   # 显示(Jupyter 可省略)

常见环境配置

Jupyter: %matplotlib inline 自动显示
脚本:   plt.show() 或 savefig
服务器: 只保存图片不显示(Agg 后端)

Matplotlib Pyplot

Matplotlib Pyplot

Pyplot 是 Matplotlib 的简单接口,提供类似 Matlab 的函数式绘图。

基本绘图函数

import matplotlib.pyplot as plt

# 折线图
plt.plot(x, y)

# 散点图
plt.scatter(x, y)

# 柱状图
plt.bar(x, y)

# 饼图
plt.pie(y)

# 直方图
plt.hist(data)

# 显示
plt.show()

绘图流程

1. 准备数据
2. 调用绘图函数(可多次叠加)
3. 添加装饰(标题/标签/图例)
4. 显示或保存

import matplotlib.pyplot as plt

x = [1, 2, 3, 4]
y1 = [1, 4, 9, 16]
y2 = [2, 4, 6, 8]

plt.plot(x, y1, label="y=x²")    # 叠加
plt.plot(x, y2, label="y=2x")
plt.xlabel("X 轴")
plt.ylabel("Y 轴")
plt.title("多曲线图")
plt.legend()           # 图例
plt.grid(True)         # 网格
plt.show()

figure 与 axes

figure: 画布(整个图像)
axes:   画布上的坐标区(可多个)

plt.figure(figsize=(8, 6))    # 画布尺寸(英寸)
plt.subplot(1, 2, 1)          # 1行2列第1个

面向对象方式(推荐进阶)

fig, ax = plt.subplots()      # 画布 + 坐标区
ax.plot(x, y)
ax.set_title("标题")
ax.set_xlabel("X")
fig.savefig("out.png")
plt.show()

Matplotlib 绘图标记

Matplotlib 绘图标记

标记(marker)是数据点在图表上的符号,用 marker 参数控制。

常用标记

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y = [2, 4, 1, 5, 3]

plt.plot(x, y, marker="o")     # 圆点
plt.plot(x, y, marker="*")     # 星号
plt.plot(x, y, marker="s")     # 方块
plt.plot(x, y, marker="^")     # 三角
plt.plot(x, y, marker="D")     # 菱形
plt.plot(x, y, marker="x")     # 叉号

# marker 取值
"."  点      ","  像素
"o"  圆      "v"/"^"/"<"/">" 三角形
"1"/"2"/"3"/"4" 三脚架
"s"  方形    "p"  五边形
"*"  星号    "h"/"H" 六边形
"+"  "x"     "D"/"d" 菱形
"|"  竖线    "_"  横线

标记样式参数

plt.plot(x, y,
    marker="o",
    markersize=10,        # 大小
    markerfacecolor="red",  # 填充色
    markeredgecolor="black",  # 边缘色
    markeredgewidth=2,    # 边缘宽
)

# 简写组合
plt.plot(x, y, "o-r")     # 标记o 实线- 红色r
# 格式: [marker][line][color]
# "o--b" 圆形 虚线 蓝色

markevery(间隔显示)

plt.plot(x, y, marker="o", markevery=2)   # 每2个显示标记
plt.plot(x, y, marker="o", markevery=5)

散点图标记

plt.scatter(x, y, s=50, c="red", marker="^", alpha=0.7)
# s: 点大小  c: 颜色  alpha: 透明度

Matplotlib 绘图线

Matplotlib 绘图线

控制线条的样式:颜色、类型、宽度、透明度。

线型(linestyle)

plt.plot(x, y, linestyle="-")     # 实线(默认)
plt.plot(x, y, linestyle="--")    # 虚线
plt.plot(x, y, linestyle=":")     # 点线
plt.plot(x, y, linestyle="-.")    # 点划线
plt.plot(x, y, linestyle="None")  # 无线条(仅标记)

# 简写
plt.plot(x, y, "--")
plt.plot(x, y, ":")

颜色(color)

plt.plot(x, y, color="red")
plt.plot(x, y, color="#ff5733")       # 十六进制
plt.plot(x, y, color=(0.2, 0.5, 0.8)) # RGB 元组
plt.plot(x, y, color="blue", alpha=0.5)  # 透明度

# 单字母简写
r 红  g 绿  b 蓝  c 青  m 品红  y 黄  k 黑  w 白

线宽(linewidth)

plt.plot(x, y, linewidth=3)     # 宽度(默认1)
plt.plot(x, y, lw=5)            # 简写

完整样式组合

plt.plot(x, y,
    color="steelblue",
    linestyle="--",
    linewidth=2,
    marker="o",
    markersize=8,
    alpha=0.8,
)

多条线对比

plt.plot(x, y1, "r-", label="方案A")
plt.plot(x, y2, "b--", label="方案B")
plt.plot(x, y3, "g:", label="方案C")
plt.legend()

风格预设(style)

plt.style.use("ggplot")       # 预设风格
plt.style.use("seaborn-v0_8")
plt.style.use("dark_background")
plt.style.available           # 查看所有风格

Matplotlib 轴标签和标题

Matplotlib 轴标签和标题

为图表添加标题、轴标签与图例,让信息完整。

标题与标签

import matplotlib.pyplot as plt

x = [1, 2, 3, 4]
y = [10, 20, 15, 25]

plt.plot(x, y)

plt.title("销售额趋势", fontsize=16)      # 标题
plt.xlabel("月份", fontsize=12)           # X轴标签
plt.ylabel("销售额(万元)", fontsize=12)   # Y轴标签

plt.show()

标题样式

plt.title("标题",
    fontsize=18,
    color="blue",
    fontweight="bold",
    loc="center",       # left/center/right
    pad=20,             # 距离
)

图例(legend)

plt.plot(x, y1, label="产品A")
plt.plot(x, y2, label="产品B")

plt.legend(loc="upper right")   # 位置
plt.legend(loc="best")          # 自动最佳(默认)

# loc 取值: upper right / upper left / lower right
#           lower left / center / right / best

自定义刻度

plt.xticks([1, 2, 3, 4], ["一月", "二月", "三月", "四月"])
plt.yticks([0, 10, 20, 30])

# 旋转标签
plt.xticks(rotation=45)

文本标注

plt.text(2, 18, "峰值", fontsize=12, color="red")
plt.annotate("最大值", xy=(3, 25), xytext=(2, 27),
    arrowprops=dict(arrowstyle="->", color="gray"))
# xy: 标注点  xytext: 文字位置

设置范围

plt.xlim(0, 5)
plt.ylim(0, 30)
# 或 plt.axis([xmin, xmax, ymin, ymax])

Matplotlib 网格线

Matplotlib 网格线

网格线帮助读取数据值,用 grid() 控制。

基本网格

import matplotlib.pyplot as plt

x = [1, 2, 3, 4]
y = [2, 4, 6, 8]

plt.plot(x, y)
plt.grid(True)      # 显示网格

plt.show()

网格样式

plt.grid(
    color="gray",      # 颜色
    linestyle="--",    # 线型
    linewidth=0.5,     # 线宽
    alpha=0.6,         # 透明度
)

只显示某轴网格

plt.grid(axis="x")    # 只 X 轴
plt.grid(axis="y")    # 只 Y 轴

主次网格

# 主网格
plt.grid(True, which="major", alpha=0.8)

# 次网格(需先设置次刻度)
plt.minorticks_on()
plt.grid(True, which="minor", linestyle=":", alpha=0.3)

面向对象方式

fig, ax = plt.subplots()
ax.plot(x, y)
ax.grid(True, linestyle="--", alpha=0.6)

应用建议

数据密集时网格帮助对齐
浅色细网格不喧宾夺主
精确读取用网格+刻度标签

Matplotlib 绘制多图

Matplotlib 绘制多图

在一个画布上绘制多个图表,或在一个图中叠加多条曲线。

subplot(子图)

import matplotlib.pyplot as plt

# 2行2列的第1个子图
plt.subplot(2, 2, 1)
plt.plot([1, 2, 3], [1, 4, 9])
plt.title("图1")

plt.subplot(2, 2, 2)
plt.plot([1, 2, 3], [1, 2, 3])
plt.title("图2")

plt.subplot(2, 2, 3)
plt.bar([1, 2, 3], [3, 1, 2])
plt.title("图3")

plt.subplot(2, 2, 4)
plt.scatter([1, 2, 3], [2, 1, 3])
plt.title("图4")

plt.tight_layout()   # 自动调整间距
plt.show()

subplots(推荐,面向对象)

fig, axes = plt.subplots(2, 2, figsize=(10, 8))

axes[0, 0].plot(x1, y1)
axes[0, 1].scatter(x2, y2)
axes[1, 0].bar(x3, y3)
axes[1, 1].hist(data)

# 扁平访问
for ax in axes.flat:
    ax.grid(True)

plt.tight_layout()
plt.show()

不均衡子图

# 3行, 第1行占2列
plt.subplot(3, 1, 1)   # 或 gridspec
# 用 subplot2grid
plt.subplot2grid((3, 3), (0, 0), colspan=2)  # 跨2列
plt.subplot2grid((3, 3), (0, 2), rowspan=2)  # 跨2行

共享坐标轴

fig, axes = plt.subplots(2, 1, sharex=True)  # 共享X轴
# 便于对比相同时间范围的数据

多图叠加

# 同一坐标系叠加多条曲线(直接多次调用)
plt.plot(x, y1)
plt.plot(x, y2)
plt.plot(x, y3)
plt.legend()

Matplotlib 子图

Matplotlib 子图

深入子图的高级用法:创建、布局、共享轴。

subplots 完整用法

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)

# 1行3列
fig, axes = plt.subplots(1, 3, figsize=(12, 4))

axes[0].plot(x, np.sin(x))
axes[0].set_title("sin(x)")

axes[1].plot(x, np.cos(x))
axes[1].set_title("cos(x)")

axes[2].plot(x, np.tan(x))
axes[2].set_ylim(-5, 5)
axes[2].set_title("tan(x)")

plt.tight_layout()
plt.show()

共享轴与返回值

# sharex/sharey 共享坐标轴
fig, axes = plt.subplots(2, 1, sharex=True, sharey=False)

# 返回
# fig: 画布对象
# axes: 坐标区数组(numpy 数组)

# squeeze=False 保证二维数组
fig, axes = plt.subplots(2, 2, squeeze=False)
axes[0][0].plot(...)

GridSpec 精细布局

import matplotlib.gridspec as gridspec

fig = plt.figure(figsize=(10, 6))
gs = gridspec.GridSpec(3, 3, figure=fig)

ax1 = fig.add_subplot(gs[0, :])      # 第0行全宽
ax2 = fig.add_subplot(gs[1, 0:2])    # 第1行前2列
ax3 = fig.add_subplot(gs[1:, 2])     # 第2-3行第3列
ax4 = fig.add_subplot(gs[2, 0])      # 第3行第1列
ax5 = fig.add_subplot(gs[2, 1])      # 第3行第2列

# 设置间距
gs.update(wspace=0.3, hspace=0.4)

双坐标轴(twinx)

fig, ax1 = plt.subplots()

# 左侧轴
ax1.plot(x, y1, color="blue")
ax1.set_ylabel("温度(°C)", color="blue")

# 右侧轴(共享X)
ax2 = ax1.twinx()
ax2.plot(x, y2, color="red", linestyle="--")
ax2.set_ylabel("湿度(%)", color="red")

plt.show()

subplot_mosaic(新式布局)

fig, axes = plt.subplot_mosaic([
    ["a", "b"],
    ["c", "b"],
])

axes["a"].plot(x, y1)
axes["b"].plot(x, y2)
axes["c"].plot(x, y3)

Matplotlib 散点图

Matplotlib 散点图

散点图展示两个变量的关系,可编码大小与颜色。

基础散点图

import matplotlib.pyplot as plt
import numpy as np

x = np.random.rand(50) * 100
y = np.random.rand(50) * 100

plt.scatter(x, y)
plt.title("散点图")
plt.xlabel("X")
plt.ylabel("Y")
plt.show()

大小与颜色编码

np.random.seed(42)
x = np.random.randn(100)
y = np.random.randn(100)
sizes = np.random.randint(20, 200, 100)   # 点大小
colors = np.random.randn(100)             # 颜色值

plt.scatter(x, y,
    s=sizes,          # 大小
    c=colors,         # 颜色
    cmap="viridis",   # 颜色映射
    alpha=0.6,        # 透明度
)
plt.colorbar()        # 颜色条
plt.show()

分类着色

# 三组数据不同颜色
x1, y1 = np.random.randn(2, 30)
x2, y2 = np.random.randn(2, 30)
x3, y3 = np.random.randn(2, 30)

plt.scatter(x1, y1, c="red", label="类别A")
plt.scatter(x2, y2, c="blue", label="类别B")
plt.scatter(x3, y3, c="green", label="类别C")
plt.legend()
plt.show()

气泡图

# 用点大小表示第三个维度(人口/销量等)
plt.scatter(gdp, life_expectancy, s=population / 10000, alpha=0.5)

趋势分析示例

# 散点 + 回归线
x = np.linspace(0, 10, 50)
y = 2 * x + 1 + np.random.normal(0, 2, 50)

plt.scatter(x, y, alpha=0.6, label="数据点")

# 拟合直线
m, b = np.polyfit(x, y, 1)
plt.plot(x, m * x + b, "r-", label=f"拟合线 y={m:.2f}x+{b:.2f}")

plt.legend()
plt.show()

Matplotlib 柱状图

Matplotlib 柱状图

柱状图比较分类数据的数值大小。

基础柱状图

import matplotlib.pyplot as plt

categories = ["苹果", "香蕉", "橙子", "葡萄"]
values = [25, 18, 30, 22]

plt.bar(categories, values, color="steelblue")
plt.title("水果销量")
plt.ylabel("销量(吨)")
plt.show()

横向柱状图

plt.barh(categories, values, color="coral")
plt.xlabel("销量(吨)")

分组柱状图

import numpy as np

x = np.arange(len(categories))   # 位置
width = 0.35                     # 柱宽

plt.bar(x - width/2, values1, width, label="2024年")
plt.bar(x + width/2, values2, width, label="2025年")

plt.xticks(x, categories)
plt.legend()
plt.show()

堆叠柱状图

plt.bar(x, v1, label="男生")
plt.bar(x, v2, bottom=v1, label="女生")   # bottom 堆叠
plt.legend()

柱状图样式

plt.bar(categories, values,
    color=["red", "green", "blue", "orange"],  # 每柱颜色
    edgecolor="black",    # 边框
    linewidth=1,
    alpha=0.8,
)

# 突出某柱
colors = ["gray"] * len(values)
colors[2] = "red"         # 高亮橙子
plt.bar(categories, values, color=colors)

数值标注

bars = plt.bar(categories, values)
for bar in bars:
    height = bar.get_height()
    plt.text(bar.get_x() + bar.get_width()/2, height,
             str(height), ha="center", va="bottom")

Matplotlib 饼图

Matplotlib 饼图

饼图展示各部分占比,适合少数类别的组成分析。

基础饼图

import matplotlib.pyplot as plt

labels = ["Python", "Java", "JavaScript", "C++"]
sizes = [40, 25, 20, 15]

plt.pie(sizes, labels=labels)
plt.title("编程语言占比")
plt.show()

饼图高级样式

plt.pie(sizes,
    labels=labels,
    colors=["#ff9999", "#66b3ff", "#99ff99", "#ffcc99"],
    autopct="%1.1f%%",     # 显示百分比
    startangle=90,         # 起始角度
    explode=(0.05, 0, 0, 0),  # 分离(突出)
    shadow=True,           # 阴影
)

plt.axis("equal")   # 正圆形
plt.show()

环形图(甜甜圈)

plt.pie(sizes, labels=labels, autopct="%1.1f%%",
        wedgeprops=dict(width=0.4))   # 环形
plt.show()

子图饼图

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))

ax1.pie(sizes1, labels=labels1, autopct="%1.0f%%")
ax1.set_title("2024年")

ax2.pie(sizes2, labels=labels2, autopct="%1.0f%%")
ax2.set_title("2025年")

注意

1. 类别过多(>7)时不易阅读,改用柱状图
2. 占比相差悬殊时慎用(小份额看不清)
3. 顺序从 12 点方向顺时针(可用 startangle 调整)

Matplotlib 直方图

Matplotlib 直方图

直方图展示数值数据的分布,是统计可视化的基础。

基础直方图

import matplotlib.pyplot as plt
import numpy as np

data = np.random.randn(1000)   # 1000个正态分布数据

plt.hist(data, bins=30)        # 30个柱
plt.title("数据分布")
plt.xlabel("值")
plt.ylabel("频数")
plt.show()

直方图参数

plt.hist(data,
    bins=20,           # 柱数(或边界数组)
    range=(-3, 3),     # 取值范围
    density=True,      # 归一化为概率密度
    cumulative=True,   # 累积分布
    color="skyblue",
    edgecolor="black",
    alpha=0.7,
)

多组对比

data1 = np.random.normal(0, 1, 1000)
data2 = np.random.normal(2, 1.5, 1000)

plt.hist(data1, bins=30, alpha=0.6, label="A组", color="blue")
plt.hist(data2, bins=30, alpha=0.6, label="B组", color="red")
plt.legend()
plt.show()

自定义边界

# 自定义分组边界
bins = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
plt.hist(scores, bins=bins, edgecolor="black")

直方图 vs 柱状图

直方图: 连续数据分布,柱之间无间隙
柱状图: 分类数据比较,柱之间有间隙

数据分布分析示例

# 学生成绩分布
scores = np.random.randint(40, 100, 200)

plt.hist(scores, bins=12, color="seagreen", edgecolor="white")
plt.axvline(scores.mean(), color="red", linestyle="--",
            label=f"平均分: {scores.mean():.1f}")
plt.legend()
plt.show()

Matplotlib 箱线图

Matplotlib 箱线图

箱线图展示数据的分布特征:中位数、四分位数、异常值。

基础箱线图

import matplotlib.pyplot as plt
import numpy as np

# 多组数据
data = [np.random.normal(0, 1, 100) for _ in range(4)]

plt.boxplot(data, labels=["组1", "组2", "组3", "组4"])
plt.title("箱线图")
plt.show()

箱线图解读

箱子: 25% ~ 75%(四分位距 IQR)
箱中横线: 中位数(50%)
须(whisker): 正常范围(1.5×IQR)
圆圈: 异常值(outlier)

箱线图样式

plt.boxplot(data,
    labels=["组1", "组2", "组3"],
    patch_artist=True,        # 填充箱子
    boxprops=dict(facecolor="lightblue"),
    medianprops=dict(color="red", linewidth=2),
    whiskerprops=dict(color="gray"),
    flierprops=dict(marker="o", markerfacecolor="red", markersize=6),
    vert=True,                # 垂直(False横向)
    showmeans=True,           # 显示均值
)

横向箱线图

plt.boxplot(data, vert=False, labels=["组1", "组2", "组3"])

分布对比应用

# 不同模型误差分布对比
model1_errors = np.random.randn(100) * 1.0
model2_errors = np.random.randn(100) * 0.5
model3_errors = np.random.randn(100) * 2.0

plt.boxplot([model1_errors, model2_errors, model3_errors],
            labels=["模型A", "模型B", "模型C"])
plt.ylabel("误差")
plt.title("模型误差对比")
plt.show()

小提琴图(进阶)

# 显示完整分布形状(seaborn 常用)
# 需安装 seaborn
import seaborn as sns
sns.violinplot(data=[model1_errors, model2_errors])

Matplotlib 3D 图

Matplotlib 3D 图

Matplotlib 支持 3D 绘图,通过 mpl_toolkits.mplot3d。

3D 散点图

import matplotlib.pyplot as plt
import numpy as np

# 启用 3D
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection="3d")

x = np.random.randn(100)
y = np.random.randn(100)
z = np.random.randn(100)

ax.scatter(x, y, z, c=z, cmap="viridis", s=30)
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
plt.show()

3D 曲面图

from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure(figsize=(9, 6))
ax = fig.add_subplot(111, projection="3d")

# 网格数据
x = np.linspace(-5, 5, 50)
y = np.linspace(-5, 5, 50)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))

ax.plot_surface(X, Y, Z,
    cmap="viridis",
    rstride=1, cstride=1,
    alpha=0.9,
)
plt.show()

3D 线图

fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")

t = np.linspace(0, 20, 500)
x = np.sin(t)
y = np.cos(t)
z = t

ax.plot(x, y, z, linewidth=2, color="red")
plt.show()

3D 柱状图

x = np.arange(4)
y = np.arange(4)
X, Y = np.meshgrid(x, y)
Z = np.random.rand(4, 4)

ax.bar3d(X.ravel(), Y.ravel(), np.zeros(16),
         dx=0.6, dy=0.6, dz=Z.ravel(),
         color="steelblue", alpha=0.8)

注意

3D 图交互有限(旋转需手动)
大数据集 3D 渲染慢
探索性分析常用,正式报告多用 2D

Matplotlib 图像

Matplotlib 图像

用 imshow 显示图像,处理矩阵数据可视化。

显示图像

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

img = mpimg.imread("photo.jpg")   # 读取图像
plt.imshow(img)
plt.axis("off")   # 隐藏坐标轴
plt.show()

显示矩阵(热力图)

import numpy as np

# 随机矩阵
matrix = np.random.rand(10, 10)

plt.imshow(matrix, cmap="hot", interpolation="nearest")
plt.colorbar()
plt.show()

常用 cmap

viridis    默认推荐(视觉友好)
hot / cool / jet   连续色
gray       灰度
RdBu       红蓝(负正对比)
Blues      蓝色渐变
Set1 / tab10  分类色

热力图(数据矩阵)

# 相关性矩阵热力图
data = np.random.randn(100, 5)
corr = np.corrcoef(data.T)

plt.imshow(corr, cmap="RdBu", vmin=-1, vmax=1)
plt.colorbar()
plt.xticks(range(5), ["A", "B", "C", "D", "E"])
plt.yticks(range(5), ["A", "B", "C", "D", "E"])
plt.show()

图像处理可视化

# 卷积核/特征图可视化(深度学习)
fig, axes = plt.subplots(1, 4, figsize=(12, 3))
for i, ax in enumerate(axes):
    ax.imshow(feature_maps[i], cmap="gray")
    ax.axis("off")

保存高质量图

plt.savefig("chart.png",      # 文件名
    dpi=300,          # 分辨率
    bbox_inches="tight",  # 去除空白
    transparent=False,
)

Matplotlib 与 Pandas

Matplotlib 与 Pandas

Pandas 与 Matplotlib 配合,数据分析可视化一条龙。

DataFrame 直接绘图

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({
    "月份": ["1月", "2月", "3月", "4月"],
    "销售额": [120, 150, 130, 180],
    "成本": [80, 90, 85, 100],
})

# 折线图
df.plot(x="月份", y=["销售额", "成本"], kind="line")

# 柱状图
df.plot(x="月份", y="销售额", kind="bar")

# 饼图
df.plot(y="销售额", kind="pie", autopct="%1.0f%%")

plt.show()

plot kind 类型

df.plot(kind="line")    折线(默认)
df.plot(kind="bar")     柱状
df.plot(kind="barh")    横向柱
df.plot(kind="hist")    直方
df.plot(kind="box")     箱线
df.plot(kind="scatter", x="a", y="b")  散点
df.plot(kind="area")    面积

时间序列

df = pd.DataFrame({
    "date": pd.date_range("2026-01-01", periods=30, freq="D"),
    "value": np.random.randn(30).cumsum(),
})
df.plot(x="date", y="value", figsize=(10, 5))
plt.title("30天趋势")
plt.show()

分组聚合可视化

# 按类别分组求均值
df.groupby("category")["amount"].mean().plot(kind="bar")

# 数据透视
pivot = df.pivot_table(values="amount", index="month",
                       columns="city", aggfunc="sum")
pivot.plot(kind="bar", figsize=(10, 6))

多子图快捷方式

# subplots=True 每个列一个子图
df.plot(subplots=True, layout=(2, 2), figsize=(10, 8))
plt.tight_layout()

集成建议

数据清洗用 Pandas,绘图用 Matplotlib
复杂图表用 Matplotlib 原生 API
快速探索用 DataFrame.plot

Matplotlib 保存与样式

Matplotlib 保存与样式

导出图片的格式控制与主题样式管理。

保存图片

plt.savefig("chart.png")              # PNG
plt.savefig("chart.jpg")              # JPG
plt.savefig("chart.pdf")              # PDF(矢量)
plt.savefig("chart.svg")              # SVG(矢量)
plt.savefig("chart.png", dpi=300)     # 高分辨率
plt.savefig("chart.png", bbox_inches="tight")  # 紧凑

# 保存前关闭坐标轴/边框等可优化效果

图表尺寸

# 指定画布尺寸(英寸)
plt.figure(figsize=(10, 6))

# 或 subplots
fig, ax = plt.subplots(figsize=(10, 6))
# 1英寸 = 96像素(默认 dpi=100)

预设风格

import matplotlib.pyplot as plt

plt.style.available   # 查看所有风格
# ['Solarize_Light2', 'bmh', 'classic', 'dark_background',
#  'fast', 'fivethirtyeight', 'ggplot', 'grayscale',
#  'seaborn-v0_8', 'tableau-colorblind10', ...]

plt.style.use("ggplot")           # 全局
plt.style.use("seaborn-v0_8-darkgrid")

# 临时风格(上下文)
with plt.style.context("dark_background"):
    plt.plot(x, y)
    plt.savefig("dark.png")

自定义 rcParams

plt.rcParams.update({
    "figure.figsize": (10, 6),      # 默认尺寸
    "font.size": 12,                # 字体大小
    "axes.grid": True,              # 网格
    "axes.titlesize": 16,
    "lines.linewidth": 2,
    "figure.dpi": 100,
    "savefig.dpi": 300,
})

中文字体配置(持久)

# 每次绘图前配置(或写入启动文件)
plt.rcParams["font.sans-serif"] = ["SimHei", "PingFang SC"]
plt.rcParams["axes.unicode_minus"] = False

动画(进阶)

from matplotlib.animation import FuncAnimation

# 动态更新数据实现动画
# 保存 GIF/视频
# animation.save("anim.gif", writer="pillow")

Matplotlib 集成

Matplotlib 集成

Matplotlib 与机器学习、Web 等场景的集成。

机器学习可视化

# 训练曲线
import matplotlib.pyplot as plt

plt.plot(history["loss"], label="训练损失")
plt.plot(history["val_loss"], label="验证损失")
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.legend()
plt.title("训练曲线")
plt.show()

# 混淆矩阵
from sklearn.metrics import ConfusionMatrixDisplay
ConfusionMatrixDisplay.from_predictions(y_true, y_pred)
plt.show()

# ROC 曲线
from sklearn.metrics import roc_curve, auc
fpr, tpr, _ = roc_curve(y_true, y_prob)
plt.plot(fpr, tpr, label=f"AUC={auc(fpr, tpr):.3f}")
plt.plot([0, 1], [0, 1], "k--")
plt.xlabel("假阳性率"); plt.ylabel("真阳性率")
plt.legend(); plt.show()

特征重要性

# 树模型的特征重要性
importances = model.feature_importances_
plt.barh(feature_names, importances, color="steelblue")
plt.xlabel("重要性")
plt.show()

Jupyter Notebook

%matplotlib inline        # 行内显示
%matplotlib notebook      # 交互模式
plt.show()                # 或直接显示

# 多图并排
fig, axes = plt.subplots(1, 2)

Web 集成

# 保存图片供 Web 使用
plt.savefig("static/chart.png", bbox_inches="tight")

# Flask 动态生成
@app.route("/chart.png")
def chart():
    plt.figure()
    plt.plot(x, y)
    buf = io.BytesIO()
    plt.savefig(buf, format="png")
    plt.close()
    buf.seek(0)
    return send_file(buf, mimetype="image/png")

导出交互图

# 交互式图表替代方案:
# plotly / bokeh / pyecharts
# Matplotlib 也可转 HTML(需 mpld3)

与 Excel 集成

# 输出图片给 Excel 使用
plt.savefig("report_chart.png", dpi=200)
# 或用 openpyxl 插入单元格

Matplotlib 总结

Matplotlib 总结

恭喜完成 Matplotlib 教程!回顾知识体系并给出进阶建议。

知识体系回顾

  • 基础:安装、Pyplot 接口、绘图流程(figure/axes)
  • 样式:标记、线型、颜色、网格、标签标题图例
  • 布局:多图叠加、subplot/subplots、GridSpec、双坐标轴
  • 图表类型:折线、散点、柱状、饼图、直方图、箱线图、3D、图像
  • 工程:保存(dpi/格式)、风格、rcParams、中文配置
  • 集成:Pandas、机器学习、Web、Jupyter

选图指南

趋势变化:   折线图
分类比较:   柱状图
两变量关系: 散点图
占比构成:   饼图/环形图
数值分布:   直方图/箱线图
多变量关系: 热力图/散点矩阵
时间序列:   折线图+时间轴

进阶方向

1. Seaborn: 统计图表(更美观便捷)
2. Plotly:  交互式图表
3. pyecharts: 中文生态交互图表
4. 自定义: 颜色映射、图例、坐标轴细节
5. 动画: FuncAnimation 动态可视化

实践建议

1. 先画对,再画美
2. 标题/标签/单位必须完整
3. 颜色统一、避免花哨
4. 图表大小与内容匹配
5. 保存 dpi=300 保证清晰
6. 常用函数封装为工具模块复用

常见坑

1. 中文乱码 → 配置字体
2. 负号显示方块 → axes.unicode_minus=False
3. 多图重叠 → tight_layout()
4. 图片模糊 → dpi 提高
5. 忘记 show/savefig

可视化是数据沟通的桥梁。掌握 Matplotlib,你的数据分析报告将更具说服力。

第 1 / 20 节