Matplotlib 教程(千字长文)

Matplotlib 教程:从零开始绘制数据可视化图表

在数据驱动的时代,我们每天都在面对大量的数字和信息。如何让这些枯燥的数字“说话”?答案就是数据可视化。而 Matplotlib,作为 Python 生态中最核心的绘图库之一,正是实现这一目标的利器。

它就像一位专业的“数据翻译官”,能把原始数据转化为直观的图形语言。无论是展示销售趋势、分析实验结果,还是呈现科研数据,Matplotlib 都能胜任。对于初学者来说,掌握它意味着打开通往数据世界的大门;对于中级开发者,它是构建复杂可视化系统的基础工具。

本篇 Matplotlib 教程将带你从安装环境开始,逐步掌握核心绘图技能,最终能够独立完成实用的图表创作。我们不会堆砌术语,而是通过一个个真实案例,让你在动手实践中真正理解。


安装与环境准备

在使用 Matplotlib 之前,你需要确保 Python 环境已配置好。推荐使用 Python 3.7 及以上版本。如果你还没有安装 Matplotlib,可以通过 pip 命令快速完成:

pip install matplotlib

安装完成后,可以在 Python 交互环境中测试是否成功:

import matplotlib.pyplot as plt

plt.plot([1, 2, 3, 4], [1, 4, 2, 3])
plt.show()

如果弹出一个窗口显示一条折线图,说明安装成功!这个测试用例虽然简单,但已经涵盖了 Matplotlib 的基本工作流程:导入库 → 构建数据 → 绘图 → 显示结果。

提示:在 Jupyter Notebook 中使用 Matplotlib 时,建议添加 %matplotlib inline 魔法命令,这样图像会直接嵌入文档中,便于调试。


基础图表类型与绘图语法

Matplotlib 支持多种图表类型,其中最常用的是折线图、柱状图和散点图。我们先从最基础的折线图入手。

折线图:数据流动的轨迹

想象一下,你正在记录每天的步数。折线图就像是你脚印在时间轴上的延伸,清晰地展现变化趋势。

import matplotlib.pyplot as plt

days = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
steps = [8000, 9200, 7500, 10100, 8800, 12000, 11000]

plt.plot(days, steps, marker='o', linestyle='-', color='blue', linewidth=2)

plt.title('一周步数变化趋势', fontsize=16)
plt.xlabel('星期', fontsize=12)
plt.ylabel('步数', fontsize=12)

plt.grid(True, alpha=0.3)

plt.show()

代码说明:

  • marker='o':在每个数据点上添加圆形标记,让数据更易识别。
  • linestyle='-':设置线条为实线,也可以是 '--'(虚线)或 ':'(点线)。
  • color='blue':设定线条颜色,支持英文名或十六进制颜色码。
  • linewidth=2:控制线条粗细。
  • plt.grid(True, alpha=0.3):添加半透明网格,帮助对齐数据点。

柱状图:对比差异的利器

当你要比较不同类别的数值时,柱状图是最佳选择。它像一排排整齐的积木,直观展现大小差异。

import matplotlib.pyplot as plt

products = ['A', 'B', 'C', 'D', 'E']
sales = [150, 200, 180, 230, 170]

plt.barh(products, sales, color='lightgreen', edgecolor='black', height=0.6)

plt.title('各产品销量对比', fontsize=16)
plt.xlabel('销量(单位:件)', fontsize=12)
plt.ylabel('产品', fontsize=12)

for i, v in enumerate(sales):
    plt.text(v + 5, i, str(v), va='center', fontsize=10)

plt.tight_layout()

plt.show()

代码说明:

  • barh() 表示横向柱状图,适合类别名称较长的情况。
  • height=0.6 控制柱子的宽度。
  • edgecolor='black' 为柱子添加边框,增强视觉区分。
  • plt.text() 用于在柱子右侧添加具体数值,提升信息密度。
  • tight_layout() 自动调整边距,防止标签被裁剪。

多图合并与子图布局

在实际项目中,我们常常需要在一个画布上展示多个相关图表。Matplotlib 提供了 subplotsubplots 两种方式实现。

使用 subplots 创建网格布局

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

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

ax1.plot(x, y1, color='red', label='sin(x)')
ax1.set_title('正弦函数图像', fontsize=14)
ax1.set_ylabel('y = sin(x)')
ax1.grid(True, alpha=0.3)
ax1.legend()

ax2.plot(x, y2, color='blue', label='cos(x)')
ax2.set_title('余弦函数图像', fontsize=14)
ax2.set_xlabel('x (弧度)')
ax2.set_ylabel('y = cos(x)')
ax2.grid(True, alpha=0.3)
ax2.legend()

plt.tight_layout()

plt.show()

核心要点:

  • fig, (ax1, ax2) = plt.subplots(2, 1) 创建一个包含两个子图的图形对象。
  • 每个 ax(Axes)对象独立控制一个子图,可分别设置标题、标签、样式。
  • 使用 ax1.plot() 而非 plt.plot(),确保图形绘制在正确的子图上。
  • figsize=(10, 6) 控制整个图像的尺寸,单位为英寸。

自定义样式与美化技巧

一个好看的图表,不仅传递信息,也体现专业度。Matplotlib 提供丰富的自定义选项。

样式主题切换

import matplotlib.pyplot as plt

plt.style.use('seaborn-v0_8')  # 推荐使用新版样式

categories = ['A', 'B', 'C', 'D']
values = [3, 7, 2, 5]

plt.bar(categories, values, color='purple', alpha=0.7)

plt.title('使用 Seaborn 风格的柱状图', fontsize=16)
plt.xlabel('类别')
plt.ylabel('数值')
plt.grid(True, axis='y', alpha=0.4)

plt.show()

推荐样式:

  • seaborn-v0_8:现代、柔和,适合科研和报告。
  • ggplot:类似 R 的 ggplot2 风格,简洁优雅。
  • fivethirtyeight:新闻风格,适合媒体发布。

颜色与字体优化

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

fig, ax = plt.subplots(figsize=(8, 5))

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

ax.plot(x, y, marker='s', markersize=8, color='#FF6B6B', linewidth=3)

ax.set_title('自定义字体与颜色', fontsize=18, fontweight='bold', color='#2C3E50')
ax.set_xlabel('X 轴', fontsize=12, color='#34495E')
ax.set_ylabel('Y 轴', fontsize=12, color='#34495E')

ax.tick_params(axis='both', labelsize=10, colors='#7F8C8D')

ax.set_facecolor('#F8F9FA')

plt.tight_layout()
plt.show()

关键设置说明:

  • font.sans-serif:指定中文字体,避免乱码。
  • axes.unicode_minus = False:确保负号正常显示。
  • color='#FF6B6B':使用十六进制颜色代码,精确控制色调。
  • set_facecolor():为坐标轴背景添加柔和底色。

实战案例:分析学生成绩分布

让我们用 Matplotlib 完成一个完整的数据可视化项目。假设你有一组学生的数学与英语成绩,想分析它们的分布与相关性。

import matplotlib.pyplot as plt
import numpy as np

np.random.seed(42)
math_scores = np.random.normal(75, 15, 100)  # 均值 75,标准差 15
english_scores = np.random.normal(70, 12, 100)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))

ax1.hist(math_scores, bins=15, alpha=0.7, color='skyblue', edgecolor='black')
ax1.set_title('数学成绩分布', fontsize=14)
ax1.set_xlabel('分数')
ax1.set_ylabel('人数')
ax1.grid(True, alpha=0.3)

ax2.scatter(math_scores, english_scores, alpha=0.6, color='green', s=40)
ax2.set_title('数学与英语成绩相关性', fontsize=14)
ax2.set_xlabel('数学成绩')
ax2.set_ylabel('英语成绩')
ax2.grid(True, alpha=0.3)

z = np.polyfit(math_scores, english_scores, 1)
p = np.poly1d(z)
ax2.plot(math_scores, p(math_scores), "r--", alpha=0.8, linewidth=1.5)

plt.tight_layout()


plt.show()

项目意义:

  • 通过直方图观察成绩是否呈正态分布。
  • 通过散点图发现两科成绩是否存在正相关。
  • 趋势线帮助判断关联强度,为教学改进提供依据。

总结与建议

通过本篇 Matplotlib 教程,你已经掌握了绘制基础图表、管理子图、美化样式以及实战项目的核心技能。Matplotlib 并非只能画静态图,它还支持动画、3D 图形、交互式绘图等进阶功能,为后续学习打下坚实基础。

建议初学者从“画一个好看的小图表”开始,逐步尝试复杂组合。中级开发者可以探索 pandas 与 Matplotlib 的结合,实现数据清洗与可视化的无缝衔接。

记住:好的图表不是越花哨越好,而是要准确、清晰、有说服力。当你能用一张图讲清一个数据故事时,你就真正掌握了 Matplotlib 的精髓。