杰瑞科技汇

Matplotlib如何快速上手绘图?

Matplotlib 超详细教程

Matplotlib 是 Python 最基础、最强大的数据可视化库之一,它功能强大,高度可定制,几乎可以绘制任何你想要的静态、动态和交互式图表。

Matplotlib如何快速上手绘图?-图1
(图片来源网络,侵删)

目录

  1. 核心概念:理解 Matplotlib 的结构

    • Figure (画布)
    • Axes (坐标系/子图)
    • Axis (坐标轴)
    • Artist (艺术家)
  2. 入门:绘制你的第一张图

    • 最简单的绘图流程
    • plt.show() 的作用
  3. 基本绘图元素详解

    • 折线图 (plot)
    • 散点图 (scatter)
    • 柱状图 (bar, barh)
    • 直方图 (hist)
    • 饼图 (pie)
    • 箱线图 (boxplot)
  4. 图表个性化:让图表更专业

    Matplotlib如何快速上手绘图?-图2
    (图片来源网络,侵删)
    • 和标签 (title, xlabel, ylabel)
    • 设置图例 (legend)
    • 设置坐标轴范围 (xlim, ylim)
    • 设置刻度和刻度标签 (xticks, yticks)
    • 添加网格 (grid)
    • 线条样式和标记
    • 颜色设置
    • 保存图片 (savefig)
  5. 进阶:多图与子图布局

    • plt.subplot():简单网格布局
    • plt.subplots():创建整个 Figure 和 Axes
    • GridSpec:更灵活的复杂布局
  6. 高级主题:文本、注释与样式

    • 添加文本 (text, annotate)
    • 使用样式表 (plt.style.use)
    • 配置参数 (rcParams)
  7. 总结与最佳实践


核心概念:理解 Matplotlib 的结构

在开始绘图之前,理解 Matplotlib 的三个核心对象至关重要:

Matplotlib如何快速上手绘图?-图3
(图片来源网络,侵删)
  • Figure (画布):整个图表的窗口或页面,你可以把它想象成一个画板,你可以在上面画一个或多个图。
  • Axes (坐标系/子图):这是 Figure 上的一个绘图区域,它包含了两个(或三个)Axis 对象、刻度、标签、标题等,一个 Figure 可以包含多个 Axes,我们通常所说的“图”指的就是一个 Axes。
  • Axis (坐标轴):数据的坐标轴,包括 X 轴和 Y 轴,它负责定义数据域、数据 ticks 和 labels。
  • Artist (艺术家):所有在 Figure 上可见的元素都是 Artist 的子类,包括 Figure, Axes, Axis, Line2D, Text 等,当你调用一个绘图函数时,它其实是在创建一个或多个 Artist 对象并将其添加到 Axes 上。

重要提示:Matplotlib 提供了两种主要的 API:

  1. pyplot (OO) APImatplotlib.pyplot 模块提供了一个类似 MATLAB 的接口,非常适合快速绘制简单的图表,它通过隐式地创建和管理 Figure 和 Axes 来简化操作,大多数初学者从这里开始。
  2. 面向对象 API:更推荐用于复杂或自定义的图表,这种方式让你可以显式地获取和控制 Figure 和 Axes 对象,从而更灵活地进行操作。

本教程将主要介绍 pyplot API,并在适当的时候引入面向对象 API 的优势。

入门:绘制你的第一张图

确保你已经安装了 Matplotlib 和 NumPy(通常用于生成数据):

pip install matplotlib numpy

最简单的绘图流程

import matplotlib.pyplot as plt
import numpy as plt
# 1. 准备数据
x = np.linspace(0, 10, 100) # 生成 0 到 10 之间的 100 个点
y = np.sin(x)
# 2. 创建图形并绘图
plt.plot(x, y)
# 3. 显示图形
plt.show()

代码解释

  1. import matplotlib.pyplot as plt:导入 Matplotlib 的 pyplot 模块,并简写为 plt,这是惯例。
  2. x = np.linspace(...): 使用 NumPy 创建一组均匀分布的数据点,作为 X 轴数据。
  3. y = np.sin(x): 计算每个 x 点对应的正弦值,作为 Y 轴数据。
  4. plt.plot(x, y): 这是核心绘图函数,它会根据提供的数据自动创建一个 Figure 和一个 Axes,并在 Axes 上绘制一条折线。
  5. plt.show(): 将图形显示出来,在 Jupyter Notebook 或类似环境中,这步通常可以省略,因为图表会自动渲染。

plt.show() 的作用

plt.show() 会启动一个事件循环,打开一个图形窗口并等待你关闭它,在一个 Python 脚本中,plt.show() 之前所有的绘图命令都会被缓存起来,直到 plt.show() 被调用,它们才会被一次性渲染出来,这意味着你可以先定义多个图表,最后再统一显示。

基本绘图元素详解

Matplotlib 支持几乎所有常见的图表类型。

折线图 (plot)

import matplotlib.pyplot as plt
import numpy as np
# 准备数据
x = np.linspace(0, 2 * np.pi, 400)
y = np.sin(x ** 2)
# 绘制
plt.plot(x, y)"A simple plot") # 添加标题
plt.xlabel("X-axis")       # 添加 X 轴标签
plt.ylabel("Y-axis")       # 添加 Y 轴标签
plt.show()

散点图 (scatter)

import matplotlib.pyplot as plt
import numpy as np
# 生成随机数据
np.random.seed(0)
x = np.random.rand(50)
y = np.random.rand(50)
colors = np.random.rand(50)
sizes = 1000 * np.random.rand(50)
# 绘制散点图
plt.scatter(x, y, c=colors, s=sizes, alpha=0.5, cmap='viridis')
plt.colorbar() # 显示颜色条"Scatter Plot")
plt.show()

柱状图 (bar, barh)

import matplotlib.pyplot as plt
# 准备数据
categories = ['A', 'B', 'C', 'D']
values = [15, 30, 45, 10]
# 绘制垂直柱状图
plt.bar(categories, values, color=['red', 'blue', 'green', 'yellow'])"Vertical Bar Chart")
plt.ylabel("Value")
plt.show()
# 绘制水平柱状图
plt.barh(categories, values, color=['red', 'blue', 'green', 'yellow'])"Horizontal Bar Chart")
plt.xlabel("Value")
plt.show()

直方图 (hist)

直方图用于展示数据的分布情况。

import matplotlib.pyplot as plt
import numpy as np
# 生成正态分布数据
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
# 绘制直方图
plt.hist(x, bins=50, color='green', alpha=0.7) # bins 指的是柱子的数量"Histogram of IQ")
plt.xlabel("IQ")
plt.ylabel("Frequency")
plt.show()

饼图 (pie)

import matplotlib.pyplot as plt
# 准备数据
labels = 'Python', 'Java', 'C++', 'JavaScript'
sizes = [35, 30, 20, 15]
explode = (0.1, 0, 0, 0) # 突出显示第一个扇形
# 绘制饼图
plt.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
        shadow=True, startangle=90)
plt.axis('equal')  # 保证饼图是圆的"Programming Language Popularity")
plt.show()

箱线图 (boxplot)

箱线图是展示数据分布的另一种方式,可以显示中位数、四分位数和异常值。

import matplotlib.pyplot as plt
import numpy as np
# 生成多组数据
data = [np.random.normal(0, std, 100) for std in range(1, 4)]
# 绘制箱线图
plt.boxplot(data, patch_artist=True)
plt.xticks([1, 2, 3], ['Group 1', 'Group 2', 'Group 3'])"Boxplot Example")
plt.ylabel("Value")
plt.show()

图表个性化:让图表更专业

通过修改各种参数,你可以让图表信息更丰富、更美观。

import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
# 创建图形和坐标轴
fig, ax = plt.subplots(figsize=(10, 6)) # 创建一个 10x6 英寸的画布
# 绘制两条线
ax.plot(x, y1, label='sin(x)', color='blue', linestyle='--', linewidth=2)
ax.plot(x, y2, label='cos(x)', color='red', marker='o', markersize=4, linestyle='-.') # 标记点
和标签
ax.set_title('Sine and Cosine Waves', fontsize=16, pad=20)
ax.set_xlabel('X-axis (radians)', fontsize=12)
ax.set_ylabel('Y-axis', fontsize=12)
# 设置图例
ax.legend(loc='upper right', fontsize=10) # loc 可以是 'upper left', 'lower right' 等
# 设置坐标轴范围
ax.set_xlim([0, 10])
ax.set_ylim([-1.2, 1.2])
# 设置刻度
ax.set_xticks(np.arange(0, 11, 2)) # 从 0 到 10,每隔 2 一个刻度
ax.set_yticks([-1, 0, 1])
# 添加网格
ax.grid(True, linestyle=':', color='gray', alpha=0.6)
# 显示
plt.show()

个性化参数总结

  • figsize=(width, height): 设置画布大小。
  • label: 为数据系列命名,用于图例。
  • color: 设置颜色 (如 'red', '#FF5733')。
  • linestyle: 线条样式 (, , , )。
  • linewidth: 线条宽度。
  • marker: 标记点样式 ('o', 's', '^', )。
  • markersize: 标记点大小。
  • set_title(): 设置标题。
  • set_xlabel(), set_ylabel(): 设置坐标轴标签。
  • legend(): 显示图例。
  • set_xlim(), set_ylim(): 设置坐标轴范围。
  • set_xticks(), set_yticks(): 设置刻度位置。
  • grid(): 显示/隐藏网格。

保存图片 (savefig)

使用 savefig 可以将图表保存为图片文件,支持多种格式(如 PNG, JPG, PDF, SVG)。

# ... (使用上面的绘图代码)
# 在 plt.show() 之前调用
fig.savefig('my_figure.png', dpi=300, bbox_inches='tight')
fig.savefig('my_figure.pdf', format='pdf')
  • dpi: 分辨率,越高图片越清晰。
  • bbox_inches='tight': 自动裁剪掉图表周围多余的空白。

进阶:多图与子图布局

你可以在一个画布上绘制多个图表,这就是子图。

plt.subplot():简单网格布局

plt.subplot(nrows, ncols, index) 创建一个子网格。

  • nrows: 行数
  • ncols: 列数
  • index: 当前子图的索引(从 1 开始,从左到右,从上到下)
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
# 创建一个 2x2 的子图网格
plt.subplot(2, 2, 1) # 第1个子图
plt.plot(x, np.sin(x))'Sin(x)')
plt.subplot(2, 2, 2) # 第2个子图
plt.plot(x, np.cos(x))'Cos(x)')
plt.subplot(2, 2, 3) # 第3个子图
plt.plot(x, np.tan(x))'Tan(x)')
plt.subplot(2, 2, 4) # 第4个子图
plt.plot(x, x**2)'x^2')
plt.tight_layout() # 自动调整子图间距,防止重叠
plt.show()

plt.subplots():创建整个 Figure 和 Axes

这是更现代、更推荐的方法,特别是当你需要操作多个子图时,它会返回一个包含 Figure 和 Axes 对象的元组。

import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
# 创建一个 2x2 的网格,并获取所有 Axes 对象
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
# axes 是一个二维数组,可以通过 axes[row, col] 来访问每个子图
axes[0, 0].plot(x, np.sin(x))
axes[0, 0].set_title('Sin(x)')
axes[0, 1].plot(x, np.cos(x))
axes[0, 1].set_title('Cos(x)')
axes[1, 0].plot(x, np.tan(x))
axes[1, 0].set_title('Tan(x)')
axes[1, 0].set_ylim([-1, 1]) # 单独设置某个子图的坐标轴范围
axes[1, 1].plot(x, x**2)
axes[1, 1].set_title('x^2')
# 使用 tight_layout 调整布局
fig.tight_layout()
plt.show()

GridSpec:更灵活的复杂布局

当你需要创建非均匀大小的子图时,GridSpec 是最佳选择。

import matplotlib.pyplot as plt
import numpy as np
# 创建一个 GridSpec 对象,定义 3 行 3 列的网格
gs = plt.GridSpec(3, 3, hspace=0.3, wspace=0.3)
fig = plt.figure(figsize=(8, 8))
# 创建第一个子图,占据第 0 行的所有列
ax1 = fig.add_subplot(gs[0, :])
ax1.plot(np.random.rand(10))
ax1.set_title('First Plot (spans all columns)')
# 创建第二个子图,占据第 1 行的前两列
ax2 = fig.add_subplot(gs[1, :2])
ax2.plot(np.random.rand(10))
ax2.set_title('Second Plot (spans two columns)')
# 创建第三个子图,占据第 1 行的第 3 列
ax3 = fig.add_subplot(gs[1, 2])
ax3.plot(np.random.rand(10))
ax3.set_title('Third Plot')
# 创建第四个子图,占据第 2 行的所有列
ax4 = fig.add_subplot(gs[2, :])
ax4.plot(np.random.rand(10))
ax4.set_title('Fourth Plot (spans all columns)')
plt.show()

高级主题:文本、注释与样式

添加文本 (text, annotate)

import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
x = np.linspace(0, 20, 1000)
ax.plot(x, np.cos(x))
# 在特定坐标点添加文本
ax.text(10, 0, 'Maximum Point', fontsize=12, ha='center') # ha 是水平对齐方式
# 添加带箭头的注释
ax.annotate('Local Minimum',
            xy=(5 * np.pi, -1),  # 箭头尖头的位置
            xytext=(10, 0),      # 文本的位置
            arrowprops=dict(facecolor='black', shrink=0.05),
            fontsize=12)
ax.set_title('Text and Annotation Example')
plt.show()

使用样式表 (plt.style.use)

Matplotlib 内置了多种预设的样式,可以快速改变图表的整体外观。

import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
y = np.sin(x)
# 尝试不同的样式
styles = ['seaborn-v0_8-whitegrid', 'ggplot', 'dark_background', 'classic']
for style in styles:
    plt.style.use(style)
    fig, ax = plt.subplots()
    ax.plot(x, y, label=f'Sin(x) in {style}')
    ax.legend()
    plt.title(f'Style: {style}')
    plt.show() # 每次显示一个

配置参数 (rcParams)

如果你想更深入地定制 Matplotlib 的默认行为,可以修改 rcParams 字典。

import matplotlib.pyplot as plt
import numpy as np
# 修改全局默认字体和大小
plt.rcParams.update({
    'font.size': 12,
    'font.family': 'serif',
    'axes.labelsize': 14,
    'axes.titlesize': 16,
    'xtick.labelsize': 10,
    'ytick.labelsize': 10,
})
x = np.linspace(0, 10, 100)
plt.plot(x, np.sin(x))"Global rcParams Example")
plt.xlabel("X-axis")
plt.ylabel("Y-axis")
plt.show()

总结与最佳实践

  1. plt.plot() 开始:对于简单的探索性数据分析,pyplot API 快速且方便。
  2. 转向面向对象 API:对于更复杂的图表、多子图或需要精细控制的场景,强烈推荐使用 fig, ax = plt.subplots() 的方式,它更清晰、更不易出错。
  3. 清晰的命名:为变量、坐标轴和标题使用描述性的名称。
  4. 不要忘记标签:一个没有标题和坐标轴标签的图表是没有意义的。
  5. 选择合适的图表类型:根据你的数据类型和分析目的选择最合适的可视化方式。
  6. 保持简洁:避免在图表上添加过多的装饰元素,以免喧宾夺主,网格、图例等应该服务于数据展示。
  7. 善用文档和示例Matplotlib 官方文档 是最好的学习资源,里面有详细的 API 说明和海量的示例代码。

这份教程涵盖了 Matplotlib 的核心知识点,通过不断练习和尝试,你将能够利用它创造出既美观又信息丰富的数据可视化作品,祝你学习愉快!

分享:
扫描分享到社交APP
上一篇
下一篇