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

Matplotlib绘制3变量6子图代码报错排查与修改方案咨询

问题说明

现有变量列表 var = [var1, var2, var3],每个元素是包含2个元素的列表:

  • var1 形状为 (129,135)
  • var2、var3 形状为 (201,321)

需要用Matplotlib绘制3行2列共6个子图,且每行对应一个独立色条。但运行提供的代码时出现三个报错:

  • AttributeError: 'AxesSubplot' object has no attribute 'add_feature'
  • AttributeError: 'AxesSubplot' object has no attribute 'gridlines'
  • AttributeError: 'AxesSubplot' object has no attribute 'set_extent'

原代码如下:

fs=12           # font size

fig, axs = plt.subplots(3, 2, figsize=(6,8), dpi=300)
titl='H_L '
fig.suptitle(titl,fontsize=fs, weight='normal')
fig.subplots_adjust(hspace= 0.4, wspace=0.5)          # gap between the subplots

for h in range (3) :
    for i in range(2) :
        ax = axs[h, i]
        sub_titl = ['H','L' ]
        ax.set_title(sub_titl[i], fontsize=fs, weight= 'bold' )
        ax.background_patch.add_feature(feature.NaturalEarthFeature(category='cultural',
                                                name='admin_1_states_provinces_lines', 
                                                scale='50m', 
                                                facecolor='none'))
        gl = ax.gridlines(crs=ccrs.PlateCarree(), 
                      linewidth=1, 
                      color='grey', 
                      alpha=0.3, 
                      linestyle='-', 
                      draw_labels=True)
        gl.top_labels = False
        gl.right_labels = False
        gl.xformatter = LONGITUDE_FORMATTER
        gl.yformatter = LATITUDE_FORMATTER
        gl.xlabel_style = {'size': fs}
        gl.ylabel_style = {'size': fs}

        clist = ['#7f0000','#a50f15','#cb181d','#ef3b2c','#fb6a4a','#fc9272','#fcbba1','#fee0d2','#92c5de','#4393c3','#2166ac','#053061']
        cmap = mcolors.ListedColormap(clist)
    # cticks = np.arange(-20,45,5)
    # norm = mcolors.BoundaryNorm(cticks, cmap.N, clip=True)
        
        bbox = [65,100,6.5,40]
        X, Y = np.meshgrid(f1.LONGITUDE, f1.LATITUDE)  # for rf_anom
        if h > 0: 
            bbox = [40,120,-10,40]                  
            ax.set_extent(bbox[h],crs=ccrs.PlateCarree())
            X, Y = np.meshgrid(f2.lon, f2.lat)  

            iax=ax.pcolormesh(X,Y,var[h][i], cmap=cmap
                       # cmap = cmap.reversed(),
                      # norm = norm,
                      )
            ax.coastlines()
    cticks1 = np.arange(-20,50,10)
    cbar = fig.colorbar(iax,ax=ax,                  # 3 different colorbar 
                          location='right',
                          pad=0.05, 
                          drawedges=True,
                          shrink=0.8, 
                          fraction=0.04,
                          aspect=18,  
                          orientation= 'vertical',
                          extend='both',
                          # ticks=cticks1
                          )                  # colorbar settings
    cbar.ax.tick_params(labelsize=fs)
报错原因&代码问题

这些报错的根源很明确:你调用的add_feature、gridlines、set_extent都是**Cartopy地理坐标轴(GeoAxes)**的专属方法,但默认plt.subplots()创建的是普通Matplotlib AxesSubplot对象,根本不支持这些地理绘图功能。

除此之外,原代码还有不少逻辑漏洞:

  1. 色条绑定逻辑混乱:原代码在每行循环结束后绑色条,但iax只在h>0时赋值,且未关联整行子图
  2. bbox[h]索引越界:bbox是长度为4的列表,h取1、2时直接索引会报错
  3. 第一行子图(h=0)未绘制任何填色内容
  4. 缩进错误:色条代码的缩进位置不对,导致执行逻辑完全不符合预期
修改后的完整代码
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.colors as mcolors
import cartopy.crs as ccrs
from cartopy.feature import NaturalEarthFeature
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER

# 假设f1、f2、var已提前定义好
fs=12           # 字体大小

# 创建带Cartopy投影的地理子图,这是解决报错的核心
fig, axs = plt.subplots(3, 2, figsize=(6,8), dpi=300,
                        subplot_kw={'projection': ccrs.PlateCarree()})
titl='H_L '
fig.suptitle(titl, fontsize=fs, weight='normal')
fig.subplots_adjust(hspace=0.4, wspace=0.5)          # 子图间距设置

# 定义自定义色标
clist = ['#7f0000','#a50f15','#cb181d','#ef3b2c','#fb6a4a','#fc9272','#fcbba1','#fee0d2','#92c5de','#4393c3','#2166ac','#053061']
cmap = mcolors.ListedColormap(clist)
cticks1 = np.arange(-20,50,10)

for h in range(3):
    row_images = []  # 存储当前行的绘图对象,用于后续创建统一色条
    for i in range(2):
        ax = axs[h, i]
        sub_titl = ['H','L']
        ax.set_title(sub_titl[i], fontsize=fs, weight='bold')
        
        # 添加省级行政边界
        state_lines = NaturalEarthFeature(category='cultural',
                                         name='admin_1_states_provinces_lines', 
                                         scale='50m', 
                                         facecolor='none', edgecolor='black')
        ax.add_feature(state_lines)
        
        # 添加网格线与经纬度标签
        gl = ax.gridlines(crs=ccrs.PlateCarree(), 
                      linewidth=1, 
                      color='grey', 
                      alpha=0.3, 
                      linestyle='-', 
                      draw_labels=True)
        gl.top_labels = False
        gl.right_labels = False
        gl.xformatter = LONGITUDE_FORMATTER
        gl.yformatter = LATITUDE_FORMATTER
        gl.xlabel_style = {'size': fs}
        gl.ylabel_style = {'size': fs}
        
        # 根据行设置绘图范围和数据网格
        if h == 0:
            bbox = [65,100,6.5,40]
            X, Y = np.meshgrid(f1.LONGITUDE, f1.LATITUDE)
            plot_data = var[h][i]
        else:
            bbox = [40,120,-10,40]
            X, Y = np.meshgrid(f2.lon, f2.lat)
            plot_data = var[h][i]
        
        ax.set_extent(bbox, crs=ccrs.PlateCarree())
        # 绘制填色图,指定坐标转换
        im = ax.pcolormesh(X, Y, plot_data, cmap=cmap, transform=ccrs.PlateCarree())
        row_images.append(im)
        # 添加海岸线
        ax.coastlines()
    
    # 为当前行创建统一色条,绑定该行的两个子图
    cbar = fig.colorbar(row_images[0], ax=axs[h, :], 
                        location='right',
                        pad=0.05, 
                        drawedges=True,
                        shrink=0.8, 
                        fraction=0.04,
                        aspect=18,  
                        orientation='vertical',
                        extend='both',
                        ticks=cticks1)
    cbar.ax.tick_params(labelsize=fs)

plt.show()
关键修改点
  1. 地理坐标轴创建:通过subplot_kw={'projection': ccrs.PlateCarree()}指定Cartopy投影,让Axes对象支持地理绘图方法,直接解决三个AttributeError
  2. 行级色条绑定:每行子图绘制完成后,将色条绑定到整行(ax=axs[h, :]),实现每行一个独立色条的需求
  3. 逻辑补全:补充了h=0时的绘图代码,确保所有子图都有内容
  4. 索引修复:去掉了错误的bbox[h]索引,直接使用完整的bbox列表设置范围
  5. 缩进修正:调整色条代码的缩进,使其在每行子图绘制完成后执行,逻辑更清晰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 19:30:02