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

matplotlib gridspec_kw报错AttributeError,求子图轴对齐解决方案

问题解决:AttributeError: GeoAxesSubplot.set() got an unexpected keyword argument 'gridspec_kw'

错误原因

gridspec_kw 不是 figure.add_subplot() 的合法参数,这个参数仅能用于 plt.subplots() 或 matplotlib.gridspec.GridSpec 的初始化环节。你直接将其传给 add_subplot(),会被当作轴对象的配置参数,而GeoAxesSubplot并不支持该参数,因此触发报错。

解决方案

针对你需要偏移子图轴以对齐直边的需求,提供两种可行实现方式:

方法1:使用 plt.subplots() 配合 gridspec_kw

通过 plt.subplots() 直接创建带GridSpec配置的子图网格,同时指定地理投影:

import matplotlib.pyplot as plt
import numpy as np
import cartopy.crs as ccrs
import cartopy.feature as cf
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter

# 创建3行3列子图网格,指定列宽度比例(示例:前两列宽度为2,第三列为1)
f, axs = plt.subplots(3, 3, figsize=(12,9), dpi=300, tight_layout=False,
                      subplot_kw={'projection': ccrs.PlateCarree()},
                      gridspec_kw={'width_ratios': [2,2,1]})

# 提取需要的5个子图
ax1, ax2, ax3, ax4, ax5 = axs[0,0], axs[0,1], axs[1,0], axs[1,1], axs[2,0]

# 隐藏未使用的子图
for ax in axs[0,2], axs[1,2], axs[2,1], axs[2,2]:
    ax.set_visible(False)

# 后续处理ax1的代码保持原有逻辑
inter = np.linspace(-5,5, num=11, endpoint=True)
lat = f222['xlat']
lon = f222['xlon']

pr = ax1.contourf(lon, lat, f222.tmp.mean('time'), inter, 
                  transform=ccrs.PlateCarree(), cmap='RdGy_r', extend='both')
ax1.coastlines(resolution='50m', color='black', lw=0.5)
x_lons = np.arange(-20,20,10)
y_lats = np.arange(5,25,5)
ax1.tick_params(labelsize=7)
lon_formatter = LongitudeFormatter(zero_direction_label=True, number_format='.0f')
lat_formatter = LatitudeFormatter()
ax1.xaxis.set_major_formatter(lon_formatter)
ax1.yaxis.set_major_formatter(lat_formatter)
ax1.set_xticks(x_lons, minor=False, crs=ccrs.PlateCarree())
ax1.set_yticks(y_lats, minor=False, crs=ccrs.PlateCarree())
ax1.text(-23., 5.5, r'(a)', fontsize=7, fontweight="bold")
ax1.text(-15., 25, r'CRU - Grell', fontsize=10, fontweight="bold")
ax1.add_feature(cf.BORDERS, lw=0.5)
ax1.add_feature(cf.COASTLINE, lw=0.5)

# 其他子图按相同逻辑处理即可

方法2:手动创建GridSpec添加子图

如果需要更灵活的子图位置控制,可手动初始化GridSpec后逐个添加子图:

import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
import numpy as np
import cartopy.crs as ccrs
import cartopy.feature as cf
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter

f = plt.figure(figsize=(12,9), dpi=300, tight_layout=False)
# 创建3行3列的GridSpec,指定列宽度比例
gs = GridSpec(3, 3, width_ratios=[2,2,1])

# 逐个添加子图,指定GridSpec位置和地理投影
ax1 = f.add_subplot(gs[0,0], projection=ccrs.PlateCarree())
ax2 = f.add_subplot(gs[0,1], projection=ccrs.PlateCarree())
ax3 = f.add_subplot(gs[1,0], projection=ccrs.PlateCarree())
ax4 = f.add_subplot(gs[1,1], projection=ccrs.PlateCarree())
ax5 = f.add_subplot(gs[2,0], projection=ccrs.PlateCarree())

# 隐藏未使用的子图
for ax in [f.add_subplot(gs[0,2]), f.add_subplot(gs[1,2]), 
           f.add_subplot(gs[2,1]), f.add_subplot(gs[2,2])]:
    ax.set_visible(False)

# 后续ax1的处理代码保持原有逻辑
inter = np.linspace(-5,5, num=11, endpoint=True)
lat = f222['xlat']
lon = f222['xlon']

pr = ax1.contourf(lon, lat, f222.tmp.mean('time'), inter, 
                  transform=ccrs.PlateCarree(), cmap='RdGy_r', extend='both')
ax1.coastlines(resolution='50m', color='black', lw=0.5)
x_lons = np.arange(-20,20,10)
y_lats = np.arange(5,25,5)
ax1.tick_params(labelsize=7)
lon_formatter = LongitudeFormatter(zero_direction_label=True, number_format='.0f')
lat_formatter = LatitudeFormatter()
ax1.xaxis.set_major_formatter(lon_formatter)
ax1.yaxis.set_major_formatter(lat_formatter)
ax1.set_xticks(x_lons, minor=False, crs=ccrs.PlateCarree())
ax1.set_yticks(y_lats, minor=False, crs=ccrs.PlateCarree())
ax1.text(-23., 5.5, r'(a)', fontsize=7, fontweight="bold")
ax1.text(-15., 25, r'CRU - Grell', fontsize=10, fontweight="bold")
ax1.add_feature(cf.BORDERS, lw=0.5)
ax1.add_feature(cf.COASTLINE, lw=0.5)

# 其他子图按相同逻辑处理即可

关键说明

  • width_ratios 是GridSpec的核心参数,用于控制列的宽度比例,你可根据实际需求调整数值,实现子图轴的偏移对齐。
  • 两种方法均适配你使用的matplotlib 3.6.2版本,且完全兼容cartopy的地理投影轴。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 01:20:25