在 Matplotlib 绘图上叠加图像

MatplotlibMatplotlibBeginner
立即练习

This tutorial is from open-source community. Access the source code

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在数据可视化中,你有时可能想在绘图中添加徽标、水印或其他图像元素。本教程将演示如何在 Matplotlib 绘图上叠加图像,将其置于绘图内容前方并使其半透明。

你将学习如何使用 matplotlib.figure.Figure 类的 figimage 方法在绘图上定位图像,以及使用 matplotlib.image 模块的 imread 方法加载图像数据。

在本教程结束时,你将能够创建带有自定义图像叠加层的专业可视化效果,这对于品牌推广、添加水印或增强数据展示的视觉吸引力非常有用。

虚拟机使用提示

虚拟机启动完成后,点击左上角切换到 Notebook 标签页,即可访问 Jupyter Notebook 进行练习。

click-notebook
有时,你可能需要等待几秒钟,让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动进行。

如果你在学习过程中遇到问题,随时向 Labby 提问。学习结束后请提供反馈,我们会及时为你解决问题。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL matplotlib(("Matplotlib")) -.-> matplotlib/BasicConceptsGroup(["Basic Concepts"]) matplotlib(("Matplotlib")) -.-> matplotlib/PlottingDataGroup(["Plotting Data"]) matplotlib(("Matplotlib")) -.-> matplotlib/PlotCustomizationGroup(["Plot Customization"]) matplotlib/BasicConceptsGroup -.-> matplotlib/importing_matplotlib("Importing Matplotlib") matplotlib/BasicConceptsGroup -.-> matplotlib/figures_axes("Understanding Figures and Axes") matplotlib/PlottingDataGroup -.-> matplotlib/line_plots("Line Plots") matplotlib/PlottingDataGroup -.-> matplotlib/scatter_plots("Scatter Plots") matplotlib/PlottingDataGroup -.-> matplotlib/bar_charts("Bar Charts") matplotlib/PlotCustomizationGroup -.-> matplotlib/titles_labels("Adding Titles and Labels") matplotlib/PlotCustomizationGroup -.-> matplotlib/axis_ticks("Axis Ticks Customization") subgraph Lab Skills matplotlib/importing_matplotlib -.-> lab-49029{{"在 Matplotlib 绘图上叠加图像"}} matplotlib/figures_axes -.-> lab-49029{{"在 Matplotlib 绘图上叠加图像"}} matplotlib/line_plots -.-> lab-49029{{"在 Matplotlib 绘图上叠加图像"}} matplotlib/scatter_plots -.-> lab-49029{{"在 Matplotlib 绘图上叠加图像"}} matplotlib/bar_charts -.-> lab-49029{{"在 Matplotlib 绘图上叠加图像"}} matplotlib/titles_labels -.-> lab-49029{{"在 Matplotlib 绘图上叠加图像"}} matplotlib/axis_ticks -.-> lab-49029{{"在 Matplotlib 绘图上叠加图像"}} end

创建 Jupyter Notebook 并导入所需库

在 Notebook 的第一个单元格中,输入以下代码以导入必要的库:

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.cbook as cbook
import matplotlib.image as image

让我们来了解一下这些库的作用:

  • matplotlib.pyplot(别名为 plt):一组使 Matplotlib 像 MATLAB 一样工作的函数,为创建绘图提供了便捷的接口。
  • numpy(别名为 np):Python 中用于科学计算的基础包,我们将用它来进行数据处理。
  • matplotlib.cbook:Matplotlib 的实用函数集合,包括获取示例数据的函数。
  • matplotlib.image:Matplotlib 中与图像相关功能的模块,我们将用它来读取和显示图像。

点击 Notebook 顶部的“运行”按钮或按 Shift + Enter 来运行该单元格。

libraries-imported

此单元格执行完成后应无任何输出,这表明所有库都已成功导入。

加载并查看图像

既然我们已经导入了所需的库,接下来就需要加载想要叠加到绘图上的图像。Matplotlib 提供了一些示例图像供我们练习使用。

  1. 在你的 Notebook 中创建一个新单元格,并输入以下代码:
## Load the sample image
with cbook.get_sample_data('logo2.png') as file:
    im = image.imread(file)

## Display information about the image
print(f"Image shape: {im.shape}")
print(f"Image data type: {im.dtype}")

## Display the image
plt.figure(figsize=(4, 4))
plt.imshow(im)
plt.axis('off')  ## Hide axis
plt.title('Matplotlib Logo')
plt.show()

这段代码的功能如下:

  • 使用 cbook.get_sample_data() 从 Matplotlib 的示例数据集中加载名为 'logo2.png' 的示例图像。
  • 使用 image.imread() 将图像文件读取为 NumPy 数组。
  • 打印图像的尺寸和数据类型信息。
  • 创建一个图形,并使用 plt.imshow() 显示图像。
  • 使用 plt.axis('off') 隐藏坐标轴刻度和标签。
  • 为图形添加标题。
  • 使用 plt.show() 显示图形。
  1. 按下 Shift + Enter 运行该单元格。

输出结果应显示图像的相关信息,并展示 Matplotlib 的徽标。图像的形状表示图像的尺寸(高度、宽度、颜色通道),数据类型则告诉我们图像数据的存储方式。

image-info

这一步非常重要,因为它有助于我们了解将用作叠加层的图像。我们可以看到它的外观和尺寸,这在决定如何将其放置在绘图上时会很有用。

使用随机数据创建基本绘图

在添加图像叠加层之前,我们需要创建一个绘图,作为可视化的基础。让我们使用随机数据创建一个简单的条形图。

  1. 在你的 Notebook 中创建一个新单元格,并输入以下代码:
## Create a figure and axes for our plot
fig, ax = plt.subplots(figsize=(10, 6))

## Set a random seed for reproducibility
np.random.seed(19680801)

## Generate random data
x = np.arange(30)  ## x-axis values (0 to 29)
y = x + np.random.randn(30)  ## y-axis values (x plus random noise)

## Create a bar chart
bars = ax.bar(x, y, color='#6bbc6b')  ## Green bars

## Add grid lines
ax.grid(linestyle='--', alpha=0.7)

## Add labels and title
ax.set_xlabel('X-axis Label')
ax.set_ylabel('Y-axis Label')
ax.set_title('Bar Chart with Random Data')

## Display the plot
plt.tight_layout()
plt.show()

这段代码的功能如下:

  • 使用 plt.subplots() 创建一个具有特定大小的图形和坐标轴。
  • 设置随机种子,以确保每次运行代码时都能得到相同的随机值。
  • 生成 30 个 x 值(从 0 到 29)以及对应的 y 值(x 加上随机噪声)。
  • 使用 ax.bar() 创建一个绿色条形图。
  • 使用 ax.grid() 为绘图添加网格线。
  • 为 x 轴、y 轴添加标签,并为绘图添加标题。
  • 使用 plt.tight_layout() 调整间距,使外观更美观。
  • 使用 plt.show() 显示绘图。
  1. 按下 Shift + Enter 运行该单元格。

输出结果应显示一个绿色条形图,代表随机数据。x 轴显示从 0 到 29 的整数,y 轴显示加上随机噪声后的对应值。

这个绘图将作为下一步叠加图像的基础。注意,我们将图形对象存储在变量 fig 中,将坐标轴对象存储在变量 ax 中。我们需要这些变量来添加图像叠加层。

在绘图上叠加图像

既然我们已经创建了基础绘图,接下来就让我们将图像叠加到上面。我们将使用 figimage 方法把图像添加到图形中,并使其具有半透明效果,这样下方的绘图仍然可见。

  1. 在你的 Notebook 中创建一个新单元格,并输入以下代码:
## Create a figure and axes for our plot (same as before)
fig, ax = plt.subplots(figsize=(10, 6))

## Set a random seed for reproducibility
np.random.seed(19680801)

## Generate random data
x = np.arange(30)  ## x-axis values (0 to 29)
y = x + np.random.randn(30)  ## y-axis values (x plus random noise)

## Create a bar chart
bars = ax.bar(x, y, color='#6bbc6b')  ## Green bars

## Add grid lines
ax.grid(linestyle='--', alpha=0.7)

## Add labels and title
ax.set_xlabel('X-axis Label')
ax.set_ylabel('Y-axis Label')
ax.set_title('Bar Chart with Image Overlay')

## Load the image
with cbook.get_sample_data('logo2.png') as file:
    im = image.imread(file)

## Overlay the image on the plot
## Parameters:
## - im: the image data
## - 25, 25: x and y position in pixels from the bottom left
## - zorder=3: controls the drawing order (higher numbers are drawn on top)
## - alpha=0.5: controls the transparency (0 = transparent, 1 = opaque)
fig.figimage(im, 25, 25, zorder=3, alpha=0.5)

## Display the plot
plt.tight_layout()
plt.show()

这段代码结合了我们之前的操作,并添加了 figimage 方法,将图像叠加到绘图上。以下是 figimage 参数的详细解释:

  • im:以 NumPy 数组形式存在的图像数据。
  • 25, 25:从图形左下角开始计算的像素 x 和 y 坐标。
  • zorder=3:控制绘制顺序。数值越大,元素越会绘制在数值较小的元素之上。
  • alpha=0.5:控制图像的透明度。值为 0 表示完全透明,值为 1 表示完全不透明。
  1. 按下 Shift + Enter 运行该单元格。

输出结果应显示与之前相同的条形图,但现在 Matplotlib 徽标会叠加在左下角。徽标应该是半透明的,这样下方的绘图仍然可见。

  1. 让我们尝试不同的位置和透明度级别。创建一个新单元格并输入以下代码:
## Create a figure and axes for our plot
fig, ax = plt.subplots(figsize=(10, 6))

## Set a random seed for reproducibility
np.random.seed(19680801)

## Generate random data
x = np.arange(30)
y = x + np.random.randn(30)

## Create a bar chart
bars = ax.bar(x, y, color='#6bbc6b')
ax.grid(linestyle='--', alpha=0.7)
ax.set_xlabel('X-axis Label')
ax.set_ylabel('Y-axis Label')
ax.set_title('Bar Chart with Centered Image Overlay')

## Load the image
with cbook.get_sample_data('logo2.png') as file:
    im = image.imread(file)

## Get figure dimensions
fig_width, fig_height = fig.get_size_inches() * fig.dpi

## Calculate center position (this is approximate)
x_center = fig_width / 2 - im.shape[1] / 2
y_center = fig_height / 2 - im.shape[0] / 2

## Overlay the image at the center with higher transparency
fig.figimage(im, x_center, y_center, zorder=3, alpha=0.3)

## Display the plot
plt.tight_layout()
plt.show()

这段代码将图像放置在图形的中心,并设置了更高的透明度级别(alpha=0.3),使其更适合作为水印。

  1. 按下 Shift + Enter 运行该单元格。

输出结果应显示条形图,徽标位于中心位置,并且比之前更透明,从而产生水印效果。

创建可重复使用的图像叠加函数

为了让我们的代码更具可复用性,我们来创建一个函数,它可以将图像叠加到任何 Matplotlib 图形上。这样,我们就能轻松地将相同的效果应用到不同的绘图中。

  1. 在你的 Notebook 中创建一个新单元格,并输入以下代码:
def add_image_overlay(fig, image_path, x_pos=25, y_pos=25, alpha=0.5, zorder=3):
    """
    Add an image overlay to a matplotlib figure.

    Parameters:
    -----------
    fig : matplotlib.figure.Figure
        The figure to add the image to
    image_path : str
        Path to the image file
    x_pos : int
        X position in pixels from the bottom left
    y_pos : int
        Y position in pixels from the bottom left
    alpha : float
        Transparency level (0 to 1)
    zorder : int
        Drawing order (higher numbers are drawn on top)

    Returns:
    --------
    fig : matplotlib.figure.Figure
        The figure with the image overlay
    """
    ## Load the image
    with cbook.get_sample_data(image_path) as file:
        im = image.imread(file)

    ## Add the image to the figure
    fig.figimage(im, x_pos, y_pos, zorder=zorder, alpha=alpha)

    return fig

## Example usage: Create a scatter plot with an image overlay
fig, ax = plt.subplots(figsize=(10, 6))

## Set a random seed for reproducibility
np.random.seed(19680801)

## Generate random data for a scatter plot
x = np.random.rand(50) * 10
y = np.random.rand(50) * 10

## Create a scatter plot
ax.scatter(x, y, s=100, c=np.random.rand(50), cmap='viridis', alpha=0.7)
ax.grid(linestyle='--', alpha=0.7)
ax.set_xlabel('X-axis Label')
ax.set_ylabel('Y-axis Label')
ax.set_title('Scatter Plot with Image Overlay')

## Add the image overlay using our function
add_image_overlay(fig, 'logo2.png', x_pos=50, y_pos=50, alpha=0.4)

## Display the plot
plt.tight_layout()
plt.show()

这段代码定义了一个名为 add_image_overlay 的函数,它的功能如下:

  • 接收图形、图像路径、位置、透明度和 z 顺序等参数。
  • 加载指定的图像。
  • 使用 figimage 将图像添加到图形中。
  • 返回修改后的图形。

定义完函数后,我们通过创建一个带有随机数据的散点图,并将 Matplotlib 徽标作为叠加层添加到图中,来演示该函数的使用方法。

  1. 按下 Shift + Enter 运行该单元格。

输出结果应显示一个散点图,其中的点随机分布且颜色各异,Matplotlib 徽标以 40% 的不透明度叠加在位置 (50, 50) 处。

  1. 让我们再尝试一个折线图的示例。创建一个新单元格并输入以下代码:
## Example usage: Create a line plot with an image overlay
fig, ax = plt.subplots(figsize=(10, 6))

## Generate data for a line plot
x = np.linspace(0, 10, 100)
y = np.sin(x)

## Create a line plot
ax.plot(x, y, linewidth=2, color='#d62728')
ax.grid(linestyle='--', alpha=0.7)
ax.set_xlabel('X-axis Label')
ax.set_ylabel('Y-axis Label')
ax.set_title('Sine Wave with Image Overlay')
ax.set_ylim(-1.5, 1.5)

## Add the image overlay using our function
## Place it in the bottom right corner
fig_width, fig_height = fig.get_size_inches() * fig.dpi
with cbook.get_sample_data('logo2.png') as file:
    im = image.imread(file)
    x_pos = fig_width - im.shape[1] - 50  ## 50 pixels from the right edge

add_image_overlay(fig, 'logo2.png', x_pos=x_pos, y_pos=50, alpha=0.6)

## Display the plot
plt.tight_layout()
plt.show()

这段代码创建了一个显示正弦波的折线图,并将 Matplotlib 徽标添加到绘图的右下角。

  1. 按下 Shift + Enter 运行该单元格。

输出结果应显示一个正弦波的折线图,Matplotlib 徽标以 60% 的不透明度叠加在右下角。

这些示例展示了我们的 add_image_overlay 函数如何轻松地将图像叠加到不同类型的绘图中,使其成为自定义可视化效果的通用工具。

总结

在本教程中,你学习了如何在 Matplotlib 绘图上叠加图像,以创建水印、徽标或其他增强可视化效果的视觉元素。以下是我们所涵盖内容的总结:

  1. 导入库:我们首先导入了处理 Matplotlib 绘图和图像所需的库。
  2. 加载和检查图像:我们学习了如何使用 imread 函数加载图像,以及如何检查它们的属性。
  3. 创建基础绘图:我们创建了不同类型的绘图(条形图、散点图和折线图),作为图像叠加的基础。
  4. 叠加图像:我们使用 figimage 方法将图像放置在绘图上,并控制它们的位置、透明度和绘制顺序。
  5. 创建可重复使用的函数:我们开发了一个可重复使用的函数,以便更轻松地将图像叠加到任何 Matplotlib 图形上。

你在本教程中学到的技能可以应用于以下方面:

  • 为绘图添加水印以保护版权
  • 在可视化中包含徽标以进行品牌推广
  • 创建自定义背景元素,使图表更美观
  • 将图像与数据可视化相结合,用于演示和报告

你可以继续尝试不同类型的绘图、图像、位置和透明度级别,以创建满足你特定需求的独特且专业的可视化效果。