在单个循环中绘制带有子图的多个图形
Plotting on multiple figures with subplots in a single loop
我正在绘制两个图形,每个图形都有多个子图。我需要在一个循环中执行此操作。当我只有一个数字时,这是我所做的:
fig, ax = plt.subplots(nrows=6,ncols=6,figsize=(20, 20))
fig.subplots_adjust(hspace=.5,wspace=0.4)
plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
for x in range(1,32):
plt.subplot(6,6,x)
plt.title('day='+str(x))
plt.scatter(x1,y1)
plt.scatter(x2,y2)
plt.colorbar().set_label('Distance from ocean',rotation=270)
plt.savefig('Plots/everyday_D color.png')
plt.close()
现在我知道当你有多个数字时你需要做这样的事情:
fig1, ax1 = plt.subplots()
fig2, ax2 = plt.subplots()
但我不知道如何在循环中绘制,每个子图都在它的位置(因为如果有两个数字,你不能继续做 plt.scatter)。请具体说明我需要做什么(关于是否fig1.scatter、ax1.scatter、fig.subplots_adjust、...最后如何保存关闭)
每个pyplot函数在面向对象中都有对应的方法API。如果你真的想同时遍历两个图形的轴,这看起来像这样:
import numpy as np
import matplotlib.pyplot as plt
x1 = x2 = np.arange(10)
y1 = y2 = c = np.random.rand(10,6)
fig1, axes1 = plt.subplots(nrows=2,ncols=3)
fig1.subplots_adjust(hspace=.5,wspace=0.4)
fig2, axes2 = plt.subplots(nrows=2,ncols=3)
fig2.subplots_adjust(hspace=.5,wspace=0.4)
for i, (ax1,ax2) in enumerate(zip(axes1.flatten(), axes2.flatten())):
ax1.set_title('day='+str(i))
ax2.set_title('day='+str(i))
sc1 = ax1.scatter(x1,y1[:,i], c=c[:,i])
sc2 = ax2.scatter(x2,y2[:,i], c=c[:,i])
fig1.colorbar(sc1, ax=ax1)
fig2.colorbar(sc2, ax=ax2)
plt.savefig("plot.png")
plt.show()
plt.close()
这里你遍历了两个扁平轴数组,这样 ax1
和 ax2
就是 matplotlib axes to plot to. fig1
and fig2
are matplotlib figures (matplotlib.figure.Figure
).
为了也获得索引,使用了enumerate
。所以行
for i, (ax1,ax2) in enumerate(zip(axes1.flatten(), axes2.flatten())):
# loop code
等同于
for i in range(6):
ax1 = axes1.flatten()[i]
ax2 = axes2.flatten()[i]
# loop code
或
i = 0
for ax1,ax2 in zip(axes1.flatten(), axes2.flatten()):
# loop code
i += 1
写起来都比较长
此时您可能对以下事实感兴趣:尽管使用面向对象 API 的上述解决方案肯定更通用且更可取,但纯 pyplot 解决方案仍然是可能的。这看起来像
import numpy as np
import matplotlib.pyplot as plt
x1 = x2 = np.arange(10)
y1 = y2 = c = np.random.rand(10,6)
plt.figure(1)
plt.subplots_adjust(hspace=.5,wspace=0.4)
plt.figure(2)
plt.subplots_adjust(hspace=.5,wspace=0.4)
for i in range(6):
plt.figure(1)
plt.subplot(2,3,i+1)
sc1 = plt.scatter(x1,y1[:,i], c=c[:,i])
plt.colorbar(sc1)
plt.figure(2)
plt.subplot(2,3,i+1)
sc2 = plt.scatter(x1,y1[:,i], c=c[:,i])
plt.colorbar(sc2)
plt.savefig("plot.png")
plt.show()
plt.close()
这是一个版本,展示了如何 运行 在两个不同的图形上绘制散点图。基本上,您引用使用 plt.subplots
.
创建的轴
import matplotlib.pyplot as plt
import numpy as np
x1 = y1 = range(10)
x2 = y2 = range(5)
nRows = nCols = 6
fig1, axesArray1 = plt.subplots(nrows=nRows,ncols=nCols,figsize=(20, 20))
fig1.subplots_adjust(hspace=.5,wspace=0.4)
fig1.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
fig2, axesArray2 = plt.subplots(nrows=nRows,ncols=nCols,figsize=(20, 20))
fig2.subplots_adjust(hspace=.5,wspace=0.4)
fig2.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
days = range(1, 32)
dayRowCol = np.array([i + 1 for i in range(nRows * nCols)]).reshape(nRows, nCols)
for day in days:
rowIdx, colIdx = np.argwhere(dayRowCol == day)[0]
axis1 = axesArray1[rowIdx, colIdx]
axis1.set_title('day=' + str(day))
axis1.scatter(x1, y1)
axis2 = axesArray2[rowIdx, colIdx]
axis2.set_title('day=' + str(day))
axis2.scatter(x2, y2)
# This didn't run in the original script, so I left it as is
# plt.colorbar().set_label('Distance from ocean',rotation=270)
fig1.savefig('plots/everyday_D1_color.png')
fig2.savefig('plots/everyday_D2_color.png')
plt.close('all')
当我从 post plt.colorbar()
中获取原始代码时出现错误,所以我在答案中将其遗漏了。如果您有一个例子说明 colorbar
是如何工作的,我们可以看看如何为两个数字实现这一点,但其余代码应该按预期工作!
请注意,如果 day
every 没有出现在 dayRolCol
中,numpy 将引发错误,由您决定如何处理这种情况。此外,使用 numpy 绝对不是唯一的方法,只是我喜欢的一种方式 - 你真正需要做的就是找到一种方法 link 某个 day/plot 与 (x , y) 要绘制的轴的索引。
我正在绘制两个图形,每个图形都有多个子图。我需要在一个循环中执行此操作。当我只有一个数字时,这是我所做的:
fig, ax = plt.subplots(nrows=6,ncols=6,figsize=(20, 20))
fig.subplots_adjust(hspace=.5,wspace=0.4)
plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
for x in range(1,32):
plt.subplot(6,6,x)
plt.title('day='+str(x))
plt.scatter(x1,y1)
plt.scatter(x2,y2)
plt.colorbar().set_label('Distance from ocean',rotation=270)
plt.savefig('Plots/everyday_D color.png')
plt.close()
现在我知道当你有多个数字时你需要做这样的事情:
fig1, ax1 = plt.subplots()
fig2, ax2 = plt.subplots()
但我不知道如何在循环中绘制,每个子图都在它的位置(因为如果有两个数字,你不能继续做 plt.scatter)。请具体说明我需要做什么(关于是否fig1.scatter、ax1.scatter、fig.subplots_adjust、...最后如何保存关闭)
每个pyplot函数在面向对象中都有对应的方法API。如果你真的想同时遍历两个图形的轴,这看起来像这样:
import numpy as np
import matplotlib.pyplot as plt
x1 = x2 = np.arange(10)
y1 = y2 = c = np.random.rand(10,6)
fig1, axes1 = plt.subplots(nrows=2,ncols=3)
fig1.subplots_adjust(hspace=.5,wspace=0.4)
fig2, axes2 = plt.subplots(nrows=2,ncols=3)
fig2.subplots_adjust(hspace=.5,wspace=0.4)
for i, (ax1,ax2) in enumerate(zip(axes1.flatten(), axes2.flatten())):
ax1.set_title('day='+str(i))
ax2.set_title('day='+str(i))
sc1 = ax1.scatter(x1,y1[:,i], c=c[:,i])
sc2 = ax2.scatter(x2,y2[:,i], c=c[:,i])
fig1.colorbar(sc1, ax=ax1)
fig2.colorbar(sc2, ax=ax2)
plt.savefig("plot.png")
plt.show()
plt.close()
这里你遍历了两个扁平轴数组,这样 ax1
和 ax2
就是 matplotlib axes to plot to. fig1
and fig2
are matplotlib figures (matplotlib.figure.Figure
).
为了也获得索引,使用了enumerate
。所以行
for i, (ax1,ax2) in enumerate(zip(axes1.flatten(), axes2.flatten())):
# loop code
等同于
for i in range(6):
ax1 = axes1.flatten()[i]
ax2 = axes2.flatten()[i]
# loop code
或
i = 0
for ax1,ax2 in zip(axes1.flatten(), axes2.flatten()):
# loop code
i += 1
写起来都比较长
此时您可能对以下事实感兴趣:尽管使用面向对象 API 的上述解决方案肯定更通用且更可取,但纯 pyplot 解决方案仍然是可能的。这看起来像
import numpy as np
import matplotlib.pyplot as plt
x1 = x2 = np.arange(10)
y1 = y2 = c = np.random.rand(10,6)
plt.figure(1)
plt.subplots_adjust(hspace=.5,wspace=0.4)
plt.figure(2)
plt.subplots_adjust(hspace=.5,wspace=0.4)
for i in range(6):
plt.figure(1)
plt.subplot(2,3,i+1)
sc1 = plt.scatter(x1,y1[:,i], c=c[:,i])
plt.colorbar(sc1)
plt.figure(2)
plt.subplot(2,3,i+1)
sc2 = plt.scatter(x1,y1[:,i], c=c[:,i])
plt.colorbar(sc2)
plt.savefig("plot.png")
plt.show()
plt.close()
这是一个版本,展示了如何 运行 在两个不同的图形上绘制散点图。基本上,您引用使用 plt.subplots
.
import matplotlib.pyplot as plt
import numpy as np
x1 = y1 = range(10)
x2 = y2 = range(5)
nRows = nCols = 6
fig1, axesArray1 = plt.subplots(nrows=nRows,ncols=nCols,figsize=(20, 20))
fig1.subplots_adjust(hspace=.5,wspace=0.4)
fig1.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
fig2, axesArray2 = plt.subplots(nrows=nRows,ncols=nCols,figsize=(20, 20))
fig2.subplots_adjust(hspace=.5,wspace=0.4)
fig2.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
days = range(1, 32)
dayRowCol = np.array([i + 1 for i in range(nRows * nCols)]).reshape(nRows, nCols)
for day in days:
rowIdx, colIdx = np.argwhere(dayRowCol == day)[0]
axis1 = axesArray1[rowIdx, colIdx]
axis1.set_title('day=' + str(day))
axis1.scatter(x1, y1)
axis2 = axesArray2[rowIdx, colIdx]
axis2.set_title('day=' + str(day))
axis2.scatter(x2, y2)
# This didn't run in the original script, so I left it as is
# plt.colorbar().set_label('Distance from ocean',rotation=270)
fig1.savefig('plots/everyday_D1_color.png')
fig2.savefig('plots/everyday_D2_color.png')
plt.close('all')
当我从 post plt.colorbar()
中获取原始代码时出现错误,所以我在答案中将其遗漏了。如果您有一个例子说明 colorbar
是如何工作的,我们可以看看如何为两个数字实现这一点,但其余代码应该按预期工作!
请注意,如果 day
every 没有出现在 dayRolCol
中,numpy 将引发错误,由您决定如何处理这种情况。此外,使用 numpy 绝对不是唯一的方法,只是我喜欢的一种方式 - 你真正需要做的就是找到一种方法 link 某个 day/plot 与 (x , y) 要绘制的轴的索引。