matplotlib 中子图的多个颜色条(具有不同的 ranges/ticks)
multiple colorbars (with different ranges/ticks) for subplots in matplotlib
我正在使用 matplotlib 绘制具有不同颜色条的子图。
有关详细信息,请参阅下面的代码。
我想要实现的目标是附加的颜色条对于不同的子图具有不同的范围(刻度)。
这可以通过设置不同的 ci 来实现(见下面的代码)。
例如,左侧 2 列子图应带有范围为 0~100,21 间隔的颜色条;右侧 2 列子图应带有范围为 0~5、21 间隔的颜色条。
但是,第一个颜色条没有0~100个标签。见附图。
我想左边的子图在图案和颜色方面仍然是正确的,只有左边颜色条的 'labels' 是错误的。
我应该怎么做才能解决这个问题?
非常感谢!
fig, axs = plt.subplots(nrows=2, ncols=4, figsize=(10, 10)) #, constrained_layout=True)
fig.subplots_adjust(bottom=0.05, top=0.95, left=0.15, right=1.6,
wspace=0.1, hspace=0.15)
for i, ax in enumerate(axs.flat):
cmap = plt.get_cmap('gist_earth_r')
cmap.set_over('navy')
cmap.set_under('white')
if i < 2 or (i >= 4 and i<= 5):
ci = np.linspace(0., 100., 21)
else:
ci = np.linspace(0.,5.,21)
norm = matplotlib.colors.BoundaryNorm(ci, cmap.N)
pcm = ax.pcolormesh( x, z, cs[i], cmap=cmap, norm=norm )
ax.set_xticks([-90,-60,-30,0,30,60,90])
ax.set_xticklabels(['90S','60S','30S','0','30N','60N','90N'])
ax.set_yticks([1000,850,700,500,300,100])
ax.set_ylabel('')
ax.set_xlabel('')
ax.invert_yaxis()
ax.set_title(titles[i],loc='center',pad='5')#,fontdict=font)
ax.xaxis.set_major_formatter(ticker.NullFormatter())
ax.yaxis.set_major_formatter(ticker.NullFormatter())
fig.colorbar(pcm, ax=axs[:, :2], shrink=0.6, location='bottom',extend='both', pad=0.05)
fig.colorbar(pcm, ax=axs[:, 2:], location='bottom', shrink=0.6, extend='both', pad=0.05)
#fig.colorbar(pcm, ax=[axs[1, 1]], location='right')
plt.show()
[1]: https://i.stack.imgur.com/VDHdw.jpg
我改写了一点。主要问题是您在同一个 pcolormesh 上两次调用 colorbar,因为您是在循环之外进行的。此外,在我看来,您想要在颜色栏上应用的更改只需要将 vmin 和 vmax 提供给 pcolormesh(而不是一个标准),并在调用颜色栏时给出刻度。示例片段和下图:
import matplotlib.pyplot as plt
import numpy as np
fig, axs = plt.subplots(nrows=2, ncols=4, sharex=True, sharey=True,
figsize=(20, 16))
fig.subplots_adjust(bottom=0.05, top=0.95, left=0.15, right=1.6,
wspace=0.1, hspace=0.15)
cmap = plt.get_cmap('gist_earth_r')
cmap.set_over('navy')
cmap.set_under('white')
gridY, gridX = np.mgrid[0:1000:31 * 1j, -90:90:31 * 1j]
for i, ax in enumerate(axs.flatten(order='F')):
if i < len(axs.flatten()) / 2:
cs = np.random.default_rng().integers(101, size=(31, 31))
pcm = ax.pcolormesh(gridX, gridY, cs, vmin=0, vmax=100, cmap=cmap)
else:
cs = np.random.default_rng().integers(6, size=(31, 31))
pcm = ax.pcolormesh(gridX, gridY, cs, vmin=0, vmax=5, cmap=cmap)
if i == len(axs.flatten()) / 2 - 1:
fig.colorbar(pcm, ax=axs[:, :2], shrink=0.6, location='bottom',
pad=0.05, ticks=np.linspace(0, 100, 21))
elif i == len(axs.flatten()) - 1:
fig.colorbar(pcm, ax=axs[:, 2:], location='bottom', shrink=0.6,
pad=0.05, ticks=np.linspace(0, 5, 21))
ax.set_xticks([-90, -60, -30, 0, 30, 60, 90])
ax.set_xticklabels(['90S', '60S', '30S', '0', '30N', '60N', '90N'])
ax.invert_yaxis()
fig.savefig('so.png', bbox_inches='tight')
我正在使用 matplotlib 绘制具有不同颜色条的子图。 有关详细信息,请参阅下面的代码。
我想要实现的目标是附加的颜色条对于不同的子图具有不同的范围(刻度)。 这可以通过设置不同的 ci 来实现(见下面的代码)。 例如,左侧 2 列子图应带有范围为 0~100,21 间隔的颜色条;右侧 2 列子图应带有范围为 0~5、21 间隔的颜色条。
但是,第一个颜色条没有0~100个标签。见附图。 我想左边的子图在图案和颜色方面仍然是正确的,只有左边颜色条的 'labels' 是错误的。
我应该怎么做才能解决这个问题?
非常感谢!
fig, axs = plt.subplots(nrows=2, ncols=4, figsize=(10, 10)) #, constrained_layout=True)
fig.subplots_adjust(bottom=0.05, top=0.95, left=0.15, right=1.6,
wspace=0.1, hspace=0.15)
for i, ax in enumerate(axs.flat):
cmap = plt.get_cmap('gist_earth_r')
cmap.set_over('navy')
cmap.set_under('white')
if i < 2 or (i >= 4 and i<= 5):
ci = np.linspace(0., 100., 21)
else:
ci = np.linspace(0.,5.,21)
norm = matplotlib.colors.BoundaryNorm(ci, cmap.N)
pcm = ax.pcolormesh( x, z, cs[i], cmap=cmap, norm=norm )
ax.set_xticks([-90,-60,-30,0,30,60,90])
ax.set_xticklabels(['90S','60S','30S','0','30N','60N','90N'])
ax.set_yticks([1000,850,700,500,300,100])
ax.set_ylabel('')
ax.set_xlabel('')
ax.invert_yaxis()
ax.set_title(titles[i],loc='center',pad='5')#,fontdict=font)
ax.xaxis.set_major_formatter(ticker.NullFormatter())
ax.yaxis.set_major_formatter(ticker.NullFormatter())
fig.colorbar(pcm, ax=axs[:, :2], shrink=0.6, location='bottom',extend='both', pad=0.05)
fig.colorbar(pcm, ax=axs[:, 2:], location='bottom', shrink=0.6, extend='both', pad=0.05)
#fig.colorbar(pcm, ax=[axs[1, 1]], location='right')
plt.show()
[1]: https://i.stack.imgur.com/VDHdw.jpg
我改写了一点。主要问题是您在同一个 pcolormesh 上两次调用 colorbar,因为您是在循环之外进行的。此外,在我看来,您想要在颜色栏上应用的更改只需要将 vmin 和 vmax 提供给 pcolormesh(而不是一个标准),并在调用颜色栏时给出刻度。示例片段和下图:
import matplotlib.pyplot as plt
import numpy as np
fig, axs = plt.subplots(nrows=2, ncols=4, sharex=True, sharey=True,
figsize=(20, 16))
fig.subplots_adjust(bottom=0.05, top=0.95, left=0.15, right=1.6,
wspace=0.1, hspace=0.15)
cmap = plt.get_cmap('gist_earth_r')
cmap.set_over('navy')
cmap.set_under('white')
gridY, gridX = np.mgrid[0:1000:31 * 1j, -90:90:31 * 1j]
for i, ax in enumerate(axs.flatten(order='F')):
if i < len(axs.flatten()) / 2:
cs = np.random.default_rng().integers(101, size=(31, 31))
pcm = ax.pcolormesh(gridX, gridY, cs, vmin=0, vmax=100, cmap=cmap)
else:
cs = np.random.default_rng().integers(6, size=(31, 31))
pcm = ax.pcolormesh(gridX, gridY, cs, vmin=0, vmax=5, cmap=cmap)
if i == len(axs.flatten()) / 2 - 1:
fig.colorbar(pcm, ax=axs[:, :2], shrink=0.6, location='bottom',
pad=0.05, ticks=np.linspace(0, 100, 21))
elif i == len(axs.flatten()) - 1:
fig.colorbar(pcm, ax=axs[:, 2:], location='bottom', shrink=0.6,
pad=0.05, ticks=np.linspace(0, 5, 21))
ax.set_xticks([-90, -60, -30, 0, 30, 60, 90])
ax.set_xticklabels(['90S', '60S', '30S', '0', '30N', '60N', '90N'])
ax.invert_yaxis()
fig.savefig('so.png', bbox_inches='tight')