You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cartopy子图垂直间距过大:tight_layout无效及色条适配问题

Cartopy子图垂直空白与色条尺寸优化方案

以下代码用于绘制3列2行共6幅Cartopy地图,每列子图对应一个色条,但即使使用fig.tight_layout(),子图间仍存在大量垂直空白,同时色条尺寸需要调整:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib import colorbar, colors
import cartopy.crs as ccrs
import cartopy.feature as cf

X   = [9.9576, 11.0621, 12.1844, 9.1307, 8.409, 
       11.0108, 11.0549, 9.8648, 12.5024, 7.8343, 
       10.9308, 11.8134, 10.0792, 8.5584, 10.2759, 
       12.1019, 9.2235, 10.3348, 7.828, 10.9206]

Y   = [49.7704, 47.483, 49.6662, 47.6952, 48.4538, 
       47.8009, 49.503, 48.6656, 48.279, 48.0232, 
       49.0115, 48.3477, 50.224, 49.5063, 47.3984, 
       49.0425, 48.6883, 47.7233, 48.3647, 49.8743]

Z   = [2.3337733, -0.52256856, 0.97157093, 
       -0.50601561,  0.21645241, 0.4011776,
       -1.69798815, 1.3751253, -1.79249769, 
       -0.09767434, 0.96454293, 0.12713469, 
       -0.03112513,  1.36738838, -0.37373591,
       0.40124358, 0.77141455,  0.62646425,  
       0.52960763, -1.16011285]

fig,ax = plt.subplots(ncols=3,nrows=2,figsize=(10,7),
                      subplot_kw={'projection': ccrs.PlateCarree()})


fig.tight_layout()

vmin=min(Z)
vmax=max(Z)

for col in range(3):
    for row in range(2):
        ax[row,col].set_extent([7.5377, 14.0065, 47.221, 50.7131])
        ax[row,col].add_feature(cf.BORDERS)
        ax[row,col].add_feature(cf.STATES,linewidth=0.5)
        ax[row,col].coastlines()
        ax[row,col].set_aspect('equal')
        #fig.tight_layout()
            
        ax[row,col].scatter(X, Y, c=Z,
                        cmap="YlOrRd",
                        edgecolors='black',
                        transform=ccrs.PlateCarree(),vmin=vmin,vmax=vmax)
    
    norm = mpl.colors.Normalize(vmin=vmin, vmax=vmax)
    fig.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap="YlOrRd"),
                 ax=ax[:, col],
                shrink=0.5)

plt.savefig('stackoverflow.png', format='png',dpi=600)

解决方案

  • 移除强制等宽高比设置:删除ax[row,col].set_aspect('equal')。Cartopy在设置set_extent后会自动根据地图范围适配子图比例,强制锁定等比例会导致垂直方向出现多余空白。
  • 改用动态布局机制:在创建子图时设置constrained_layout=True,替代tight_layout()。该机制能动态识别色条等额外元素的空间占用,自动调整子图位置与间距,布局效果更稳定。
  • 优化色条尺寸与间距:调整fig.colorbar的shrink参数(例如改为0.8)让色条高度匹配子图,同时用pad参数(例如设为0.05)控制色条与子图的间距,避免留白过多。

修改后的完整代码

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
import cartopy.crs as ccrs
import cartopy.feature as cf

X   = [9.9576, 11.0621, 12.1844, 9.1307, 8.409, 
       11.0108, 11.0549, 9.8648, 12.5024, 7.8343, 
       10.9308, 11.8134, 10.0792, 8.5584, 10.2759, 
       12.1019, 9.2235, 10.3348, 7.828, 10.9206]

Y   = [49.7704, 47.483, 49.6662, 47.6952, 48.4538, 
       47.8009, 49.503, 48.6656, 48.279, 48.0232, 
       49.0115, 48.3477, 50.224, 49.5063, 47.3984, 
       49.0425, 48.6883, 47.7233, 48.3647, 49.8743]

Z   = [2.3337733, -0.52256856, 0.97157093, 
       -0.50601561,  0.21645241, 0.4011776,
       -1.69798815, 1.3751253, -1.79249769, 
       -0.09767434, 0.96454293, 0.12713469, 
       -0.03112513,  1.36738838, -0.37373591,
       0.40124358, 0.77141455,  0.62646425,  
       0.52960763, -1.16011285]

# 启用constrained_layout自动处理布局
fig, ax = plt.subplots(ncols=3, nrows=2, figsize=(10,7),
                      subplot_kw={'projection': ccrs.PlateCarree()},
                      constrained_layout=True)

vmin = min(Z)
vmax = max(Z)

for col in range(3):
    for row in range(2):
        ax[row,col].set_extent([7.5377, 14.0065, 47.221, 50.7131])
        ax[row,col].add_feature(cf.BORDERS)
        ax[row,col].add_feature(cf.STATES, linewidth=0.5)
        ax[row,col].coastlines()
            
        ax[row,col].scatter(X, Y, c=Z,
                        cmap="YlOrRd",
                        edgecolors='black',
                        transform=ccrs.PlateCarree(), vmin=vmin, vmax=vmax)
    
    norm = mpl.colors.Normalize(vmin=vmin, vmax=vmax)
    # 调整色条尺寸与间距
    fig.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap="YlOrRd"),
                 ax=ax[:, col],
                 shrink=0.8,
                 pad=0.05)

plt.savefig('stackoverflow.png', format='png', dpi=600)
plt.show()

内容的提问来源于stack exchange,提问作者AlexLee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 16:42:51