目录
subplot()、subplots()均用于Matplotlib 绘制多图,我们需要理解它的实际工作流程和返回对象的含义,才能更好的用它们来处理大型的数据。
1.从两者的区别来谈谈函数返回对象:
菜鸟教程原文解释:
- subplots 一次性创建并返回所有的子图和其 axe 对象。subplot则是分开多次添加子图。每次调用返回一个子图和对应的 ax 对象。
不知道你第一次看到这段话是否迷惑,反正我是迷了,后来看了大量教程发现这样的说法是极其模糊和不准确的。 来让我们搞懂它们吧
来看这段常见代码:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
这里fig和ax是两个subplots()的返回对象,名称当然可以自定义
实际的含义是什么呢?这个才是最重要的
我的理解:
- fig-------即figure,画窗,图形对象。
- ax-------即axex,画窗中创建的笛卡尔坐标区
上面的代码,是下面代码的精简形式:
fig = plt.figure() # 首先调用plt.figure()创建了一个**画窗对象fig**
ax = fig.add_subplot(111) # 然后再对fix创建默认的坐标区(一行一列一个坐标区)
# 这里的(111)相当于(1,1,1),当然,官方有规定,当子区域不超过9个的时候,我们可以这样简写
1.1 plt.subplot()
关于 subplot():
来看 matplotlib.pyplot.subplot 的官方解释:
注意这句:This is a wrapper of Figure.add_subplot which provides additional behavior when working with the implicit API (see the notes section).
即是对add_subplot()函数的封装调用。
1.2 add_subplot()
再来看add_subplot():
意思就是用来向画窗添加坐标区的。
那么我们可以进行总结了:
subplot()、subplots()在实际过程中,先创建了一个figure画窗,然后通过调用add_subplot()来向画窗中各个分块添加坐标区,其差别在于是分次添加(subplot())还是一次性添加(subplots()).
1.3 三者区别
下面通俗地解释 plt.subplots
和 add_subplot()
的区别,有助于更好地理解它们的用途和场景。
1.3.1 plt.subplots
和 plt.subplot
的区别
-
plt.subplots
:plt.subplots
是创建一整个图形(figure)和其中多个子图(axes)的一个方便函数。- 它一次性生成一个包含所有子图的图形,并返回图形对象和子图对象。
- 用法:
fig, axes = plt.subplots(nrows, ncols)
,其中nrows
是行数,ncols
是列数。axes
是一个包含所有子图对象的数组。
例子:
import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 2 * np.pi, 100) y_sin = np.sin(x) y_cos = np.cos(x) # 使用 plt.subplots 创建一个包含两个子图的图形 fig, axes = plt.subplots(1, 2, figsize=(10, 5)) # 绘制第一个子图 axes[0].plot(x, y_sin, label='sin(x)') axes[0].set_title('Sine Function') axes[0].set_xlabel('x') axes[0].set_ylabel('sin(x)') axes[0].legend() # 绘制第二个子图 axes[1].plot(x, y_cos, label='cos(x)') axes[1].set_title('Cosine Function') axes[1].set_xlabel('x') axes[1].set_ylabel('cos(x)') axes[1].legend() plt.tight_layout() plt.show()
-
plt.subplot
:plt.subplot
是一个逐个添加子图的函数。- 它需要你每次调用时指定行、列和子图位置,然后在这个子图上绘制内容。
- 用法:
plt.subplot(nrows, ncols, index)
,其中nrows
是行数,ncols
是列数,index
是子图位置。
例子:
import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 2 * np.pi, 100) y_sin = np.sin(x) y_cos = np.cos(x) # 创建一个包含两个子图的图形 plt.figure(figsize=(10, 5)) # 绘制第一个子图 plt.subplot(1, 2, 1) # 1行2列,第1个子图 plt.plot(x, y_sin, label='sin(x)') plt.title('Sine Function') plt.xlabel('x') plt.ylabel('sin(x)') plt.legend() # 绘制第二个子图 plt.subplot(1, 2, 2) # 1行2列,第2个子图 plt.plot(x, y_cos, label='cos(x)') plt.title('Cosine Function') plt.xlabel('x') plt.ylabel('cos(x)') plt.legend() plt.tight_layout() plt.show()
1.3.2 plt.subplots
和 add_subplot
的区别
-
plt.subplots
:- 一次性创建整个图形和多个子图,并返回图形和子图对象。
- 更加简洁和高效,尤其是当你需要创建多个子图时。
- 使用
axes
对象数组来访问和操作子图。
-
add_subplot
:- 是
Figure
对象的方法,用于逐个添加子图。 - 每次调用
add_subplot
时,都会返回一个新的子图对象。 - 适用于需要动态或条件性地添加子图的情况。
例子:
import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 2 * np.pi, 100) y_sin = np.sin(x) y_cos = np.cos(x) # 创建一个图形对象 fig = plt.figure(figsize=(10, 5)) # 添加第一个子图 ax1 = fig.add_subplot(1, 2, 1) ax1.plot(x, y_sin, label='sin(x)') ax1.set_title('Sine Function') ax1.set_xlabel('x') ax1.set_ylabel('sin(x)') ax1.legend() # 添加第二个子图 ax2 = fig.add_subplot(1, 2, 2) ax2.plot(x, y_cos, label='cos(x)') ax2.set_title('Cosine Function') ax2.set_xlabel('x') ax2.set_ylabel('cos(x)') ax2.legend() plt.tight_layout() plt.show()
- 是
1.3.3 总结
plt.subplots
更适合一次性创建和管理多个子图,代码更简洁。plt.subplot
适合逐个创建子图,灵活性更高。add_subplot
是Figure
对象的方法,适合动态添加子图。
2. 应用案例
2.1 plt.figure() + fig.add_subplot() 单个图
# 可视化联合概率密度的3D图
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection='3d')
ti_grid = np.full(alp2_grid.shape, ti_fixed_value)
joint_density = kde(np.vstack([alp2_grid.ravel(), air_density_grid.ravel(), ti_grid.ravel()])).reshape(
alp2_grid.shape)
ax.plot_surface(alp2_grid, air_density_grid, joint_density, cmap='viridis', alpha=0.7)
ax.set_xlabel('alp2')
ax.set_ylabel('air_density')
ax.set_zlabel('Density')
ax.set_title('Joint Probability')
plt.show()
2.2 plt.subplots() 单个图(简洁)
fig, ax = plt.subplots(figsize=(10, 6))
cs = ax.contourf(alp2_grid, air_density_grid, condition_density, cmap='viridis')
plt.colorbar(cs, ax=ax)
ax.set_xlabel('alp2')
ax.set_ylabel('air_density')
ax.set_title(f'Conditional Probability')
plt.show()
2.3 plt.subplots() 多图(简洁)
# 设置Seaborn风格
sns.set(style="whitegrid")
# 创建一个2x2的图形布局
fig, axes = plt.subplots(1, 3, figsize=(18, 6))
# 设置Y轴范围
y_limits = {
'alp': (-0.25, 1), # 根据数据分布调整范围
'TI': (-0.05, 0.2),
'shear': (-0.2, 0.5),
'air_density': (0.6, 1.5)
}
# 绘制'ALP'的箱线图
sns.boxplot(x='terrain', y='alp', data=data, ax=axes[0], palette='Set2')
axes[0].set_title('alp vs Terrain')
axes[0].set_xlabel('Terrain')
axes[0].set_ylabel('alp')
axes[0].set_ylim(y_limits['alp'])
axes[0].axhline(y=0.11, color='red', linewidth=0.5)
# 绘制'TI'的箱线图
sns.boxplot(x='terrain', y='TI', data=data, ax=axes[1], palette='Set2')
axes[1].set_title('TI vs Terrain')
axes[1].set_xlabel('Terrain')
axes[1].set_ylabel('TI')
axes[1].set_ylim(y_limits['TI'])
axes[1].axhline(y=0.11, color='red', linewidth=0.5)
# 绘制'Shear'的箱线图
sns.boxplot(x='terrain', y='air_density', data=data, ax=axes[2], palette='Set2')
axes[2].set_title('air_density vs Terrain')
axes[2].set_xlabel('Terrain')
axes[2].set_ylabel('air_density')
axes[2].set_ylim(y_limits['air_density'])
axes[2].axhline(y=1.0, color='red', linewidth=0.5)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 运行配置参数中的字体(font)为黑体(SimHei)
plt.rcParams['axes.unicode_minus'] = False # 运行配置参数总的轴(axes)正常显示正负号(minus)
# 显示图形
plt.tight_layout()
if status:
plt.savefig(r'df_all_medial_max_by_{}-{}.jpg'.format('terrain', datetime.now().strftime('%m%d_%H%M')))
else:
plt.show()
2.4 plt.subplot() 多图(简洁)
下面是一个使用 plt.subplot
的示例,它展示了如何在同一图中绘制多个子图。绘制两个子图:一个是正弦函数图,一个是余弦函数图。
import matplotlib.pyplot as plt
import numpy as np
# 生成数据
x = np.linspace(0, 2 * np.pi, 100)
y_sin = np.sin(x)
y_cos = np.cos(x)
# 创建一个包含两个子图的绘图区域
plt.figure(figsize=(10, 5))
# 第一个子图:正弦函数
plt.subplot(1, 2, 1) # 1行2列,第1个子图
plt.plot(x, y_sin, label='sin(x)')
plt.title('Sine Function')
plt.xlabel('x')
plt.ylabel('sin(x)')
plt.legend()
# 第二个子图:余弦函数
plt.subplot(1, 2, 2) # 1行2列,第2个子图
plt.plot(x, y_cos, label='cos(x)')
plt.title('Cosine Function')
plt.xlabel('x')
plt.ylabel('cos(x)')
plt.legend()
# 调整布局,使子图不重叠
plt.tight_layout()
# 显示图形
plt.show()
解释
- 生成数据:使用
np.linspace
生成一个从 0 到 ( 2\pi ) 的 100 个点,然后计算对应的正弦和余弦值。 - 创建绘图区域:使用
plt.figure
创建一个绘图区域,并设置图形大小为 10 x 5 英寸。 - 第一个子图:
- 使用
plt.subplot(1, 2, 1)
创建一个 1 行 2 列的子图,并选择第一个位置。 - 使用
plt.plot
绘制正弦函数。 - 添加标题、标签和图例。
- 使用
- 第二个子图:
- 使用
plt.subplot(1, 2, 2)
创建一个 1 行 2 列的子图,并选择第二个位置。 - 使用
plt.plot
绘制余弦函数。 - 添加标题、标签和图例。
- 使用
- 调整布局:使用
plt.tight_layout
调整子图之间的间距,防止重叠。 - 显示图形:使用
plt.show
显示生成的图形。
这样,就可以在同一个图形中展示多个子图,每个子图显示不同的数据或函数。这对于比较不同的数据集或展示不同的图形非常有用。
参考资料
[1] plt: subplot()、subplots()详解及返回对象figure、axes的理解 2021.11;
本站资源均来自互联网,仅供研究学习,禁止违法使用和商用,产生法律纠纷本站概不负责!如果侵犯了您的权益请与我们联系!
转载请注明出处: 免费源码网-免费的源码资源网站 » plt: subplot()、subplots()详解及返回对象figure、axes的理解
发表评论 取消回复