如何处理 matplotlib 子图中的颜色条轴 space

How to deal with the colorbar axis space in matplotlib subplots

我正在绘制四个季节的七个不同参数,如下图所示。但在最后一列 (Post-Monsoon) sub_plots 轴与 colorbar 轴妥协,这真的很尴尬!!

import matplotlib.pyplot as plt
import cartopy
import cartopy.crs as ccrs
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
import warnings
warnings.filterwarnings('ignore')

k = [1,5,9,13,17,21,25]
k1= [25,26,27,28]
k2= [4,8,12,16,20,24,28]
k3= [1,2,3,4]
k4=[25]
S=['Winter','Pre-monsoon','Monsoon','Post-Monsoon']

fig=plt.figure(figsize=(13,11), dpi=300)
for i in range(1,29):
    ax = fig.add_subplot(7,4,i, projection=ccrs.PlateCarree())
    ax.set_extent([39.9,100.5,-0.5,25.5],ccrs.PlateCarree())
    ax.add_feature(cartopy.feature.COASTLINE)
    ax.add_feature(cartopy.feature.BORDERS, linestyle='-')
    ax.add_feature(cartopy.feature.LAND, zorder=100, edgecolor='k')
    ax.set_xticks([40,50,60,70,80,90,100], crs=ccrs.PlateCarree())
    ax.set_yticks([0,5,10,15,20,25], crs=ccrs.PlateCarree())
    ax.tick_params(axis='x', length=7, width=1, bottom=True, top=True)
    ax.tick_params(axis='y', length=7, width=1, right=True, left=True)
    ax.yaxis.set_major_formatter(plt.NullFormatter())
    ax.xaxis.set_major_formatter(plt.NullFormatter())

A=D[i-1].plot.pcolormesh(ax=ax, cmap='seismic', transform=ccrs.PlateCarree(),
                  add_colorbar=False,add_labels=False)  # D contains list of parameters to be plotted
if i in k:
    gl = ax.gridlines(draw_labels=True, linestyle='--')
    gl.xlabels_top=False
    gl.xlabels_bottom=False
    gl.ylabels_right=False
    gl.xformatter=LONGITUDE_FORMATTER
    gl.yformatter=LATITUDE_FORMATTER
    gl.xlabel_style={'size':10,}
    gl.ylabel_style={'size':10,}
    ax.tick_params(axis='y', length=7, width=1, left=False)
if i in k1:
    gl = ax.gridlines(draw_labels=True, linestyle='--')
    gl.xlabels_top=False
    gl.xlabels_bottom=True
    gl.ylabels_right=False
    gl.ylabels_left=False
    gl.xformatter=LONGITUDE_FORMATTER
    gl.yformatter=LATITUDE_FORMATTER
    gl.xlabel_style={'size':10,}
    gl.ylabel_style={'size':10,}
    ax.tick_params(axis='x', length=7, width=1, bottom=False, top=True)
    ax.tick_params(axis='y', length=7, width=1, right=True, left=True)
if i in k4:
    ax.tick_params(axis='y', length=7, width=1, right=True, left=False)
if i in k2:
    ax.tick_params(axis='y', length=7, width=1, right=False)
    fig.colorbar(A,ax=ax, shrink=0.5)  #  Here is the Colorbar option 
if i in k3:
    ax.tick_params(axis='x', length=7, width=1,top=False)
    ax.title.set_text(S[i-1])
    
fig.tight_layout(h_pad=0)
plt.show()

如何在不扭曲最后一个轴的情况下调整颜色条,来自社区的任何评论 谢谢

@swatchai 的评论一如既往地准确。如果您在创建子图时想要比混合地理坐标轴与常规坐标轴更简单的方法,您可以使用 matplotlib 的 subplots_adjustaxis 命令为您的颜色映射创建专用坐标轴。

一个最小的例子:

import matplotlib.pyplot as plt
import cartopy
import cartopy.crs as ccrs
import numpy as np

fig=plt.figure(figsize=(8, 4))
for i in range(1,5):
    ax = fig.add_subplot(2,2,i, projection=ccrs.PlateCarree())
    ax.set_extent([39.9,100.5,-0.5,25.5],ccrs.PlateCarree())
    ax.add_feature(cartopy.feature.COASTLINE)


mp = ax.contourf(np.random.random_sample((10, 10))) # your contoured data here
fig.subplots_adjust(right=0.95) # create space on the right hand side
sub_ax = plt.axes([0.96, 0.55, 0.02, 0.3]) # add a small custom axis
plt.colorbar(mappable=mp, cax=sub_ax) # specify axis for colorbar to occupy with cax

这有点像 fiddle,如您所见,您必须手动对齐颜色条。但它确实回避了混合轴类型问题。

根据上述讨论和建议,我编写了脚本以沿每一行添加七个单独的颜色条轴,并且效果很好。

fig.subplots_adjust(right=0.95, wspace=0.00)

sub_ax1 = fig.add_axes([0.95, 0.79, 0.01, 0.09])
fig.colorbar(Data1, cax=sub_ax1)
sub_ax2 = fig.add_axes([0.95, 0.68, 0.01, 0.09])
fig.colorbar(Data2, cax=sub_ax2)
sub_ax3 = fig.add_axes([0.95, 0.57, 0.01, 0.09])
fig.colorbar(Data3, cax=sub_ax3)
sub_ax4 = fig.add_axes([0.95, 0.46, 0.01, 0.09])
fig.colorbar(Data4, cax=sub_ax4)
sub_ax5 = fig.add_axes([0.95, 0.35, 0.01, 0.09])
fig.colorbar(Data5, cax=sub_ax5)
sub_ax6 = fig.add_axes([0.95, 0.24, 0.01, 0.09])
fig.colorbar(Data6, cax=sub_ax6)
sub_ax7 = fig.add_axes([0.95, 0.13, 0.01, 0.09])
fig.colorbar(Data7, cax=sub_ax7)

感谢大家!!

如果你这样做:

fig, axs = plt.subplots(7, 4, subplot_kw={'projection': ccrs.PlateCarree()})
pc = axs[0, 1].pcolormesh(..)
…
fig.colorbar(pc, ax=axs[0,:])
… # etc

对于每一行,每行都有一个颜色条,所有轴的大小都相同。