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

使用Python Basemap绘图时子图排列混乱的问题排查

嘿,我帮你揪出了几个导致子图显示异常的核心问题,咱们一步步来解决:

问题1:子图编号逻辑完全错误

你用plt.subplot(621+L)来指定子图位置,但这个计算方式完全不符合matplotlib的subplot索引规则:

  • matplotlib的subplot三位数编码是行数+列数+索引(仅当行数、列数、索引都是个位数时可用),但当索引超过9时(比如第10个及以后的子图),这种拼接方式会彻底混乱(比如621+10=631会被解析成6行3列的第1个子图,完全偏离了你要的6行2列布局)。
  • 正确的做法是用逗号分隔的参数plt.subplot(nrows, ncols, index),其中index是从1开始的行优先序号。对你的6行2列布局来说,L从0到11,对应的索引就是L+1,所以应该写plt.subplot(6, 2, L+1)。

问题2:未显式创建独立的Figure

虽然plt.show()会清空当前画布,但为了避免绘图残留和混乱,最好在每个N的循环开头显式创建一个新的Figure,比如设置合适的尺寸来容纳12个子图。

问题3:色条关联不明确

当前代码里plt.colorbar()默认绑定最后一个绘图对象,最好把m.pcolor()的返回值存下来,显式传递给色条函数,确保色条和数据匹配。

修正后的完整代码

我还补全了测试所需的未定义变量,你可以直接运行测试:

# Imports
import matplotlib.cm as cm
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import numpy.ma as ma
import numpy as np

# Parameter Set-Up
N = ['A', 'B', 'C']
LAYER = ['1', '2', '3', '4', '5', '6']

# 补全测试用的变量定义
Lat_1x1 = 60
Lon_1x1 = 70
llc_LON = 139.5
urc_LON = 280.5
llc_LAT = -29.5
urc_LAT = 29.5
lon = np.linspace(llc_LON, urc_LON, Lon_1x1)
lat = np.linspace(llc_LAT, urc_LAT, Lat_1x1)

data = np.random.randint(101, size=(len(N),2*len(LAYER),Lat_1x1,Lon_1x1))

# Basemap Set-Up
# Colorbar Boundary Definitions
cmap_data = cm.rainbow_r
cmap_data.set_bad(color='white')
data_plot = np.ma.array(data, mask=np.isnan(data)) # Mask NaN
bounds_data = np.arange(0, 102, 2)
norm_data = mpl.colors.BoundaryNorm(bounds_data, cmap_data.N)

for n in np.arange(len(N)):
    # 为每个N创建独立的Figure,设置合适的尺寸
    plt.figure(figsize=(12, 18))
    for L in np.arange(2*len(LAYER)):
        # 正确指定6行2列的子图位置
        ax = plt.subplot(6, 2, L+1)
        m = Basemap(projection='cyl', 
                    llcrnrlon=llc_LON, urcrnrlon=urc_LON, 
                    llcrnrlat=llc_LAT, urcrnrlat=urc_LAT, 
                    resolution='c', ax=ax)
        m.drawcoastlines(color='k')
        m.fillcontinents(color='white') # mask land mass
        
        lons, lats = np.meshgrid(lon,lat)
        x, y = m(lons,lats)
        # 保存pcolor的返回值,用于色条关联
        im = m.pcolor(x, y, data_plot[n,L], cmap=cmap_data, norm=norm_data)
        
        plt.xlim(llc_LON, urc_LON)
        plt.xticks([150, 180, 210, 240, 270], ['150E', 'D', '150', '120', '90W']) # 140W to 80E
        plt.ylim(llc_LAT, urcr_LAT)
        plt.yticks([-30, -15, 0, 15, 30], ['30S', '15S', '0', '15N', '30N']) # 30S to 30N
        
        # 给最后一行的子图添加坐标轴标签
        if L >= 10: # 第11、12个子图(索引11和12,对应L=10和11)
            plt.xlabel('Longitude')
            plt.ylabel('Latitude')
        plt.grid()
    
    # 调整子图布局,留出色条位置
    plt.subplots_adjust(bottom=0.1, right=0.8, top=0.9, hspace=0.3, wspace=0.2)
    # 创建色条轴
    cax = plt.axes([0.82, 0.1, 0.03, 0.8])
    # 显式传入im对象,确保色条和数据匹配
    plt.colorbar(im, cax=cax, label='%')
    plt.suptitle(f'Test for {N[n]}', fontsize=16)
    plt.show()

额外优化点

  • 我添加了hspace和wspace参数来调整子图之间的间距,避免标签重叠;
  • 把色条的宽度调小了一点,避免挤占子图空间;
  • 用f-string让标题更简洁;
  • 给Basemap指定了ax=ax,确保它画在对应的子图轴上,避免潜在的轴混乱。

这样修改后,每个N对应的图都会显示完整的12个子图,位置也完全正确啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:50:38