原文标题 :How to Add an Image to a Matplotlib Plot in Python
如何在 Python 中将图像添加到 Matplotlib 图中
使用 Matplotlib 读取图像数据并将其添加到绘图中
将外部图像或图标添加到现有情节不仅可以增加美感,而且可以从整体角度增加其清晰度。外部图像可以是公司或产品的标志、国家/地区的国旗等。这些图像有助于巩固传达给读者的信息。
Python中有不同的包可用于图像处理。一些值得注意的包括 OpenCV、imageio、scikit-image、Pillow、NumPy、SciPy 和 Matplotlib。 Matplotlib 是 Python 中用于数据分析和可视化的最杰出的软件包之一。在这篇文章中,我将分享使用 Python 中的 Matplotlib 读取图像、显示图像并将其添加到现有绘图的步骤。事不宜迟,让我们开始吧。
Data
我从一个看起来像下面的数据框 df 开始。 df 包含 2011 年至 2021 年间全球太阳能光伏 (PV) 的装机容量。该数据来自 (IRENA, 2021)。
Bar plot
在这一步中,我使用 df 创建一个常规条形图。相同的代码在下面的代码块中。我删除了情节的图例,包括它的框架。我将右侧和顶部的刺设置为不可见。此外,我在绘图中添加了网格线。
使用 for 循环遍历 df 的每一行,我使用 plt.text(x, y, s) 在其顶部添加每个条的值,其中,
- x 是 X 轴上年份的位置,从 0 到 10(包括 10)
- y 和 s 均基于 df 的值,即全球太阳能光伏的年装机容量,以千兆瓦为单位。
fig, ax = plt.subplots(figsize = (12, 8))df.plot(kind = “bar”, ax = ax)plt.ylabel(“GW”)#Remove legend along with the frame
plt.legend([], frameon = False)plt.title(“Global Installed Capacity of Solar PV”)# Hide the right and top spines
ax.spines.right.set_visible(False)
ax.spines.top.set_visible(False)#Set xticks rotation to 0
plt.xticks(rotation = 0)#Add grid line
plt.grid(axis = “y”)#Adding value labels on top of bars
for i in range(len(df)):
installed = df.iloc[i][0]
plt.text(x = i — 0.2,
y = installed + 5,
s = str(installed))#Add source
plt.text(8, -100, “Source: IRENA, 2022”)plt.savefig(“../output/global solar pv trend.jpeg”,
dpi = 300)
plt.show()
结果,我得到了下面的图,它显示了过去十年全球太阳能光伏发电的急剧增长。
Reading image
可以使用 Python 中的不同包读取图像,例如 Matplotlib、OpenCV、ImageIO 和 PIL (GeeksforGeeks, 2022)。在上图中,我想在顶部中心的某处添加一个太阳能电池板的图标。我使用 Paint 软件手动绘制了太阳能电池板的徽标。使用 Matplotlib 的图像模块读取此图像,如下所示:[0]
在这里,logo 是一个 3D NumPy 形状数组 (520, 720, 4)。三维 (3D) 数组由 3 个嵌套级别的数组组成,每个维度一个 (Adamsmith, 2022)。
logo 的形状为 (M, N, 4)。 520和720是指图像的行数和列数。 4 指的是具有 RGBA 值(0-1 浮点或 0-255 整数,包括透明度)的图像,即红色、绿色、蓝色和 Alpha 中的每一个的值(Matplotlib,2020)。
Displaying image data
包含 RGB(A) 数据的 logo 可以使用 plt.imshow(logo) 在 2D 常规光栅上显示为图像。根据 logo 的形状,绘图在 X 轴和 Y 轴上分别有 720 和 520 作为界限,如下图所示:
将图像添加到 Matplotlib 图
要将徽标图像添加到条形图中,我创建了一个 OffsetBox(一个简单的容器艺术家)并在其中传递了徽标。缩放设置为 0.15,即图像原始尺寸的 15%。这个 OffsetBox 被命名为 imagebox,因为它包含了图像。
接下来,我创建了一个 AnnotationBbox,它是 imagebox 的容器。我在图的顶部中心 (5, 700) 为它指定了一个 xy 位置并隐藏了框架。这在下面的代码中表示,它与条形图的代码块一起使用:
from matplotlib.offsetbox import (OffsetImage, AnnotationBbox)#The OffsetBox is a simple container artist.
#The child artists are meant to be drawn at a relative position to its #parent.
imagebox = OffsetImage(logo, zoom = 0.15)#Annotation box for solar pv logo
#Container for the imagebox referring to a specific position *xy*.
ab = AnnotationBbox(imagebox, (5, 700), frameon = False)
ax.add_artist(ab)
结果,我可以将太阳能电池板的标志与显示全球太阳能光伏趋势的条形图一起添加。
接下来,我想在太阳能电池板周围添加一个圆圈以突出显示它。条形图中的 X 轴和 Y 轴具有不同的比例。 X 轴上的每个小刻度以 1 年为步长,而 Y 轴上的每个小刻度以 100 GW 为步长。因此,使用 plt.Circle((x,y),r) 和 ax.add_patch(circle) 添加圆会使其在图中显得不均匀。
相反,我使用了中心与 AnnotationBbox 相同的散点图。我将半径 s 设置为 20000,将标记设置为“o”形,颜色设置为“红色”,将面部颜色设置为“无”,以在太阳能电池板周围添加一个圆圈。
plt.scatter(5, 700, s = 20000, marker = “o”,
color = “red”, facecolors = “none”)
结果图如下所示。
Conclusion
将图像或图标添加到现有绘图可以增加视觉吸引力和感知。在这篇文章中,我逐步描述了如何使用 Matplotlib 将外部图像读取为二进制格式的 NumPy 数组,以及如何显示图像数据并将其添加到条形图中。在这种情况下,我提供了一个简单的示例,在条形图顶部添加太阳能电池板的标志,显示太阳能光伏装机容量的全球趋势。这篇文章的笔记本可以在这个 GitHub 存储库中找到。感谢您的阅读![0]
References
Adamsmith,2022 年。如何在 Python 中创建 3D NumPy 数组[0]
GeeksforGeeks,2022 年。用 Python 读取图像。[0]
IRENA,2021 年。统计时间序列:可再生能源趋势。[0]
Matplotlib,2020。matplotlib.axes.Axes.imshow[0]
文章出处登录后可见!