如何绘制多个子图
- 2024-11-19 08:39:00
- admin 原创
- 11
问题描述:
我对这段代码的工作原理有点困惑:
fig, axes = plt.subplots(nrows=2, ncols=2)
plt.show()
在这种情况下,无花果轴如何工作?它起什么作用?
为什么这不能起到同样的作用:
fig = plt.figure()
axes = fig.subplots(nrows=2, ncols=2)
解决方案 1:
有几种方法可以做到这一点。该subplots
方法将创建图形以及子图,然后将其存储在ax
数组中。例如:
import matplotlib.pyplot as plt
x = range(10)
y = range(10)
fig, ax = plt.subplots(nrows=2, ncols=2)
for row in ax:
for col in row:
col.plot(x, y)
plt.show()
但是,类似这样的方法也可以,但是它不是那么“干净”,因为您正在创建一个带有子图的图形,然后在它们之上添加:
fig = plt.figure()
plt.subplot(2, 2, 1)
plt.plot(x, y)
plt.subplot(2, 2, 2)
plt.plot(x, y)
plt.subplot(2, 2, 3)
plt.plot(x, y)
plt.subplot(2, 2, 4)
plt.plot(x, y)
plt.show()
解决方案 2:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2, 2)
ax[0, 0].plot(range(10), 'r') #row=0, col=0
ax[1, 0].plot(range(10), 'b') #row=1, col=0
ax[0, 1].plot(range(10), 'g') #row=0, col=1
ax[1, 1].plot(range(10), 'k') #row=1, col=1
plt.show()
解决方案 3:
您还可以在子图调用中解压轴
并设置是否要在子图之间共享 x 轴和 y 轴
像这样:
import matplotlib.pyplot as plt
# fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, sharex=True, sharey=True)
fig, axes = plt.subplots(nrows=2, ncols=2, sharex=True, sharey=True)
ax1, ax2, ax3, ax4 = axes.flatten()
ax1.plot(range(10), 'r')
ax2.plot(range(10), 'b')
ax3.plot(range(10), 'g')
ax4.plot(range(10), 'k')
plt.show()
解决方案 4:
您可能对这样一个事实感兴趣:从 matplotlib 2.1 版开始,问题中的第二段代码也能正常工作。
来自变更日志:
Figure 类现在具有 subplots 方法 Figure 类现在具有 subplots() 方法,其行为与 pyplot.subplots() 相同,但针对现有图形。
例子:
import matplotlib.pyplot as plt
fig = plt.figure()
axes = fig.subplots(nrows=2, ncols=2)
plt.show()
解决方案 5:
阅读文档:matplotlib.pyplot.subplots
pyplot.subplots()
返回fig, ax
使用符号解包为两个变量的元组
fig, axes = plt.subplots(nrows=2, ncols=2)
代码:
fig = plt.figure()
axes = fig.subplots(nrows=2, ncols=2)
不起作用,因为不是对象成员的subplots()
函数。pyplot
`Figure`
解决方案 6:
子图pandas
这个答案适用于带有的子图
pandas
,它用作matplotlib
默认绘图后端。以下是创建子图的四个选项,以
pandas.DataFrame
实现 1. 和 2. 针对宽格式的数据,为每一列创建子图。
实现 3 和 4 适用于长格式的数据,为列中的每个唯一值创建子图。
已在
python 3.8.11
,pandas 1.3.2
,matplotlib 3.4.3
,测试seaborn 0.11.2
进口和数据
import seaborn as sns # data only
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# wide dataframe
df = sns.load_dataset('planets').iloc[:, 2:5]
orbital_period mass distance
0 269.300 7.10 77.40
1 874.774 2.21 56.95
2 763.000 2.60 19.84
3 326.030 19.40 110.62
4 516.220 10.50 119.47
# long dataframe
dfm = sns.load_dataset('planets').iloc[:, 2:5].melt()
variable value
0 orbital_period 269.300
1 orbital_period 874.774
2 orbital_period 763.000
3 orbital_period 326.030
4 orbital_period 516.220
1.subplots=True
和layout
,对于每一列
使用参数
subplots=True
和layout=(rows, cols)
`pandas.DataFrame.plot`此示例使用
kind='density'
,但 有不同的选项kind
,这适用于所有选项。如果不指定kind
,则默认为线图。ax
是AxesSubplot
返回的数组pandas.DataFrame.plot
如果需要,
请参阅如何获取Figure
对象。如何保存熊猫子图
axes = df.plot(kind='density', subplots=True, layout=(2, 2), sharex=False, figsize=(10, 6))
# extract the figure object; only used for tight_layout in this example
fig = axes[0][0].get_figure()
# set the individual titles
for ax, title in zip(axes.ravel(), df.columns):
ax.set_title(title)
fig.tight_layout()
plt.show()
2. plt.subplots
,对于每一列
创建一个
Axes
带有的数组matplotlib.pyplot.subplots
,然后将axes[i, j]
或传递axes[n]
给ax
参数。该选项使用
pandas.DataFrame.plot
,但可以使用其他axes
级别绘图调用作为替代(例如sns.kdeplot
、plt.plot
等)。最简单的方法是使用或 将的子图数组折叠
Axes
成一维。请参阅vs。.ravel
`.flatten.ravel
.flatten`axes
任何需要迭代的应用于每个 的变量都与 相结合.zip
(例如cols
、axes
、colors
、palette
等)。每个对象的长度必须相同。
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 6)) # define the figure and subplots
axes = axes.ravel() # array to 1D
cols = df.columns # create a list of dataframe columns to use
colors = ['tab:blue', 'tab:orange', 'tab:green'] # list of colors for each subplot, otherwise all subplots will be one color
for col, color, ax in zip(cols, colors, axes):
df[col].plot(kind='density', ax=ax, color=color, label=col, title=col)
ax.legend()
fig.delaxes(axes[3]) # delete the empty subplot
fig.tight_layout()
plt.show()
1. 和 2 的结果。
3. plt.subplots
,对于每个组.groupby
这与 2. 类似,只是它将拉链
color
拉到物体axes
上.groupby
。
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10, 6)) # define the figure and subplots
axes = axes.ravel() # array to 1D
dfg = dfm.groupby('variable') # get data for each unique value in the first column
colors = ['tab:blue', 'tab:orange', 'tab:green'] # list of colors for each subplot, otherwise all subplots will be one color
for (group, data), color, ax in zip(dfg, colors, axes):
data.plot(kind='density', ax=ax, color=color, title=group, legend=False)
fig.delaxes(axes[3]) # delete the empty subplot
fig.tight_layout()
plt.show()
4.seaborn
图形级绘图
使用
seaborn
图形级绘图,并使用col
或row
参数。seaborn
是的高级 APImatplotlib
。请参阅seaborn:API 参考。
p = sns.displot(data=dfm, kind='kde', col='variable', col_wrap=2, x='value', hue='variable',
facet_kws={'sharey': False, 'sharex': False}, height=3.5, aspect=1.75)
sns.move_legend(p, "upper left", bbox_to_anchor=(.55, .45))
解决方案 7:
依次迭代所有子图:
fig, axes = plt.subplots(nrows, ncols)
for ax in axes.flatten():
ax.plot(x,y)
访问特定索引:
for row in range(nrows):
for col in range(ncols):
axes[row,col].plot(x[row], y[col])
解决方案 8:
将数组转换axes
为一维
使用 生成子图
plt.subplots(nrows, ncols)
,其中nrows 和 ncols都大于 1,返回一个嵌套的<AxesSubplot:>
对象数组。axes
在nrows=1
或 的情况下,没有必要展平ncols=1
,因为axes
已经是一维的,这是默认参数的结果squeeze=True
访问对象的最简单方法是使用 、 或 将数组转换为
.ravel()
1.flatten()
维.flat
。.ravel
对阵.flatten
flatten
总是返回一份副本。ravel
尽可能返回原始数组的视图。
一旦将数组
axes
转换为一维,就有多种绘图方式。这个答案与 seaborn 轴级图相关,它们具有
ax=
参数(例如sns.barplot(…, ax=ax[0])
。seaborn
是 的高级 APImatplotlib
。请参阅图形级与轴级函数,seaborn 未在定义的子图内绘图
import matplotlib.pyplot as plt
import numpy as np # sample data only
# example of data
rads = np.arange(0, 2*np.pi, 0.01)
y_data = np.array([np.sin(t*rads) for t in range(1, 5)])
x_data = [rads, rads, rads, rads]
# Generate figure and its subplots
fig, axes = plt.subplots(nrows=2, ncols=2)
# axes before
array([[<AxesSubplot:>, <AxesSubplot:>],
[<AxesSubplot:>, <AxesSubplot:>]], dtype=object)
# convert the array to 1 dimension
axes = axes.ravel()
# axes after
array([<AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>, <AxesSubplot:>],
dtype=object)
迭代扁平数组
如果子图数量多于数据数量,则会导致
IndexError: list index out of range
请尝试选项 3.,或者选择轴的子集(例如
axes[:-2]
)
for i, ax in enumerate(axes):
ax.plot(x_data[i], y_data[i])
通过索引访问每个轴
axes[0].plot(x_data[0], y_data[0])
axes[1].plot(x_data[1], y_data[1])
axes[2].plot(x_data[2], y_data[2])
axes[3].plot(x_data[3], y_data[3])
索引数据和轴
for i in range(len(x_data)):
axes[i].plot(x_data[i], y_data[i])
zip
将轴和数据放在一起,然后遍历元组列表。
for ax, x, y in zip(axes, x_data, y_data):
ax.plot(x, y)
输出
一种选择是将每个轴分配给一个变量。
fig, (ax1, ax2, ax3) = plt.subplots(1, 3)
但是,正如所写,这仅适用于nrows=1
或的情况ncols=1
。这是基于返回的数组的形状plt.subplots
,并且很快就会变得繁琐。fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
对于 2 x 2 数组。fig, (ax1, ax2) = plt.subplots(1, 2)
这对于两个子图(例如:或)最有用fig, (ax1, ax2) = plt.subplots(2, 1)
。对于更多子图,展平并遍历轴数组更有效。
解决方案 9:
您可以使用以下内容:
import numpy as np
import matplotlib.pyplot as plt
fig, _ = plt.subplots(nrows=2, ncols=2)
for i, ax in enumerate(fig.axes):
ax.plot(np.sin(np.linspace(0,2*np.pi,100) + np.pi/2*i))
或者,使用plt.subplot
返回的第二个变量:
fig, ax_mat = plt.subplots(nrows=2, ncols=2)
for i, ax in enumerate(ax_mat.flatten()):
...
ax_mat
是一个轴矩阵。其形状为 nrows x ncols。
解决方案 10:
add_subplot
您可以在以下位置使用该方法matplotlib
:
funcs = [np.cos, np.sin, np.tan, np.arctan, np.exp, np.log]
x = np.linspace(1, 10, 100)
fig = plt.figure(figsize=(10, 5))
# iterate over the function list and add a subplot for each function
for idx, func in enumerate(funcs, start=1):
ax = fig.add_subplot(2, 3, idx) # plot with 2 rows and 3 columns
ax.plot(x, func(x))
ax.set_title(func.__name__)
# add spacing between subplots
fig.tight_layout()
解决方案 11:
这是一个简单的解决方案
fig, ax = plt.subplots(nrows=2, ncols=3, sharex=True, sharey=False)
for sp in fig.axes:
sp.plot(range(10))
解决方案 12:
如果您确实想使用循环,请执行以下操作:
def plot(data):
fig = plt.figure(figsize=(100, 100))
for idx, k in enumerate(data.keys(), 1):
x, y = data[k].keys(), data[k].values
plt.subplot(63, 10, idx)
plt.bar(x, y)
plt.show()
解决方案 13:
另一个简洁的解决方案是:
// set up structure of plots
f, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(20,10))
// for plot 1
ax1.set_title('Title A')
ax1.plot(x, y)
// for plot 2
ax2.set_title('Title B')
ax2.plot(x, y)
// for plot 3
ax3.set_title('Title C')
ax3.plot(x,y)
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件