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

Python & Cartopy问题:经纬度设置被忽略,绘图范围不符预期

解决Cartopy忽略指定经纬度范围的问题

问题描述

使用Cartopy绘图时,指定的经纬度范围参数被忽略,生成图像与预期的plotcorners=[-120, -30, 120, 80]范围不符。相关代码如下:

%matplotlib inline
import matplotlib.pyplot as plt # matplotlib.pyplot ist ein Modul zum Erzeugen von Plots
import numpy as np              # numpy ist ein Modul zur Vereinfachung numerischer Berechnungen
import xarray as xr             # xarray ist das Modul zur Definition des xarray-Konstrukts
import cartopy                  # cartopy dient zum Zeichnen von Landkarten
import cartopy.crs as ccrs      
import cartopy.util as cu       # cartopy.util wird benötigt, um ein Datenfeld zyklisch zu ergänzen, 
                                # also die erste Reihe von Werten entlang der Längengrade als letzte zu wiederholen
from cartopy.mpl.gridliner import LongitudeFormatter, LatitudeFormatter
                                # LongitudeFormatter und LatitudeFormatter werden zum Zeichnen der
                                # Gitterlinien benötigt.
import scipy.stats

def cartopymap(corners):
    [leftlon, lowerlat, rightlon, upperlat] = corners
    central_lon = (leftlon+rightlon)/2
    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.set_extent([leftlon, rightlon, lowerlat, upperlat])
    ax.coastlines(resolution='110m', linewidth=1.0)
    lontics = np.arange(leftlon-10,rightlon,20)
    lattics = np.arange(0,101,10)  # Gilt nur für Nordhemisphäre
    gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,
                  linewidth=1.5, color='gray', alpha=0.5, linestyle='--')
    gl.top_labels = False
    gl.right_labels = False
    gl.xlabel_style = {'size': 12}
    gl.ylabel_style = {'size': 12}    
    gl.xformatter = LongitudeFormatter()
    gl.yformatter = LatitudeFormatter()
    return ax

def plot_filled_contours_map(title, corners, Z, levz, colormap):
    fig = plt.figure(facecolor='1.', figsize=[10, 5])
    map = cartopymap(corners)
    data, lon = cu.add_cyclic_point(Z.values, Z.lon.values)
    lat = Z.lat
    CP = map.contourf(lon, lat, data, levz, transform=ccrs.PlateCarree(), cmap=colormap, extend='both')
    map.coastlines()
    cbar = plt.colorbar(CP, ax=map, aspect=50, fraction=0.1)
    cbar.ax.tick_params(labelsize=10)
    plt.title(title, y=1.1, fontsize=14)
    
ncfile = "monthly_v_2018.nc"
tempdata = xr.open_dataset(ncfile)
levz = [-20, -17.5, -15, -12.5, -10, -7.5, -5, 5, 7.5, 10, 12.5, 15, 17.5, 20]
colormap = 'seismic'
temp = tempdata.sel(time="2018-07-01", plev="3e+04")
plotcorners = [-120, -30, 120, 80]
plot_filled_contours_map('Monthly mean of meridional wind on 300 hPa', plotcorners, temp.v, levz, colormap)

问题原因

  1. cu.add_cyclic_point会为经度数组添加循环点(重复起始经度值),导致新的经度范围超出设置的rightlon=120,而contourf绘制时会自动扩展轴范围覆盖所有数据,覆盖了之前ax.set_extent的设置。
  2. cartopymap函数中lattics固定为np.arange(0,101,10),无法适配指定的-30到80的纬度范围,导致网格线显示不符合预期。

解决方案

修改代码,在绘制等高线后重新锁定轴范围,并动态生成纬度网格线:

%matplotlib inline
import matplotlib.pyplot as plt # matplotlib.pyplot ist ein Modul zum Erzeugen von Plots
import numpy as np              # numpy ist ein Modul zur Vereinfachung numerischer Berechnungen
import xarray as xr             # xarray ist das Modul zur Definition des xarray-Konstrukts
import cartopy                  # cartopy dient zum Zeichnen von Landkarten
import cartopy.crs as ccrs      
import cartopy.util as cu       # cartopy.util wird benötigt, um ein Datenfeld zyklisch zu ergänzen, 
                                # also die erste Reihe von Werten entlang der Längengrade als letzte zu wiederholen
from cartopy.mpl.gridliner import LongitudeFormatter, LatitudeFormatter
                                # LongitudeFormatter und LatitudeFormatter werden zum Zeichnen der
                                # Gitterlinien benötigt.
import scipy.stats

def cartopymap(corners):
    [leftlon, lowerlat, rightlon, upperlat] = corners
    central_lon = (leftlon+rightlon)/2
    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.set_extent([leftlon, rightlon, lowerlat, upperlat])
    ax.coastlines(resolution='110m', linewidth=1.0)
    lontics = np.arange(leftlon-10,rightlon,20)
    # 动态生成纬度网格线,适配传入的纬度范围
    lattics = np.arange(lowerlat, upperlat + 1, 10)
    gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,
                  linewidth=1.5, color='gray', alpha=0.5, linestyle='--')
    gl.top_labels = False
    gl.right_labels = False
    gl.xlabel_style = {'size': 12}
    gl.ylabel_style = {'size': 12}    
    gl.xformatter = LongitudeFormatter()
    gl.yformatter = LatitudeFormatter()
    return ax

def plot_filled_contours_map(title, corners, Z, levz, colormap):
    fig = plt.figure(facecolor='1.', figsize=[10, 5])
    ax = cartopymap(corners)
    data, lon = cu.add_cyclic_point(Z.values, Z.lon.values)
    lat = Z.lat
    CP = ax.contourf(lon, lat, data, levz, transform=ccrs.PlateCarree(), cmap=colormap, extend='both')
    ax.coastlines()
    # 绘制后重新锁定轴范围,覆盖contourf自动扩展的范围
    ax.set_extent(corners, crs=ccrs.PlateCarree())
    cbar = plt.colorbar(CP, ax=ax, aspect=50, fraction=0.1)
    cbar.ax.tick_params(labelsize=10)
    plt.title(title, y=1.1, fontsize=14)
    
ncfile = "monthly_v_2018.nc"
tempdata = xr.open_dataset(ncfile)
levz = [-20, -17.5, -15, -12.5, -10, -7.5, -5, 5, 7.5, 10, 12.5, 15, 17.5, 20]
colormap = 'seismic'
temp = tempdata.sel(time="2018-07-01", plev="3e+04")
plotcorners = [-120, -30, 120, 80]
plot_filled_contours_map('Monthly mean of meridional wind on 300 hPa', plotcorners, temp.v, levz, colormap)

修改说明

  • 在plot_filled_contours_map函数中,绘制完contourf后调用ax.set_extent(corners, crs=ccrs.PlateCarree()),强制锁定显示范围,避免被contourf自动扩展。
  • 修改cartopymap中的lattics生成逻辑,根据传入的corners动态计算纬度网格线,适配指定的-30到80的纬度范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 08:53:12