我想让印度区域外的值变为nan,但仍然显示原值

0 投票
1 回答
46 浏览
提问于 2025-04-14 18:13
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
from cartopy.io import shapereader

ax = plt.axes(projection=ccrs.PlateCarree())

clevs = [0, 0.05, 0.1, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 0.60]

vp_fill = plt.contourf(tp.longitude, tp.latitude, tp.tprate[0,:,:]*1000, clevs,
transform=ccrs.PlateCarree(),cmap=plt.cm.viridis_r, extend='both')       

cbar = plt.colorbar(vp_fill, orientation='vertical')
cbar.ax.tick_params(labelsize=14)

# Set ticks and extent for the Indian region
ax.set_xticks([70, 75, 80, 85, 90, 95, 100], crs=ccrs.PlateCarree())
ax.set_yticks([5, 10, 15, 20, 25, 30, 35], crs=ccrs.PlateCarree())
ax.set_extent([68, 100, 5, 35])

plt.rcParams["figure.figsize"] = (12, 10)
ax.coastlines(alpha=0.8)

# Add states boundaries using the provided shapefile
shp = r'C:\Users\IMD\Swapi\india polygon\india-polygon.shp' # Replace with your actual path
ax.add_geometries(shapereader.Reader(shp).geometries(), ccrs.PlateCarree(), edgecolor='k',
facecolor='none')

plt.show()

我试过使用mask函数,但出现了一个错误:TypeError: 'NoneType'对象不可迭代。

我还尝试删除包含空值的id列,但还是出现了同样的错误。

1 个回答

0

你可以只对与印度相关的形状使用 ax.add_geometries() 这个函数。下面是一个例子,只有在印度的情况下,才会绘制来自自然地球数据的 admin_1_states_provinces 的州和省:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader

# map
fig = plt.figure(figsize=(12, 10))
ax = plt.axes(projection=ccrs.PlateCarree())

ax.set_title('India')

# ticks and extent for the Indian region
ax.set_xticks([70, 75, 80, 85, 90, 95, 100], crs=ccrs.PlateCarree())
ax.set_yticks([5, 10, 15, 20, 25, 30, 35], crs=ccrs.PlateCarree())
ax.set_extent([68, 100, 5, 35])

# get state and provinces boundaries of all countries from the Natural Earth
shapename = 'admin_1_states_provinces'
states_shp = shpreader.natural_earth(resolution='50m', category='cultural', name=shapename)
reader = shpreader.Reader(states_shp)
states = reader.records()

# show only states of India
for state in states:
    if state.attributes['admin'] == 'India':
        ax.add_geometries([state.geometry], ccrs.PlateCarree(), edgecolor='k', facecolor='none')

plt.show()

结果如下:

这里插入图片描述

如果你想只在印度显示你的填充轮廓数据,可以尝试用 matplotlib.artist.Artist.set_clip_path() 来裁剪它,使用一个从对应于印度绘制州的补丁生成的 复合路径

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader
import numpy as np
import shapely.geometry as sg
import matplotlib.patches as patches
from matplotlib.patches import PathPatch
from matplotlib.path import Path

# map
fig = plt.figure(figsize=(12, 10))
ax = plt.axes(projection=ccrs.PlateCarree())
ax.set_title('India')

# make some filled contour
clevs = [0, 0.05, 0.1, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 0.60]
x, y = np.meshgrid(np.linspace(68, 100, 100), np.linspace(5, 37, 100))
z = y / x
cs = ax.contourf(x, y, z, clevs, transform=ccrs.PlateCarree(), cmap=plt.cm.viridis_r, extend='both')

# ticks and extent for the Indian region
ax.set_xticks([70, 75, 80, 85, 90, 95, 100], crs=ccrs.PlateCarree())
ax.set_yticks([5, 10, 15, 20, 25, 30, 35], crs=ccrs.PlateCarree())
ax.set_extent([68, 100, 5, 36])

# get state and provinces boundaries of all countries from the Natural Earth
shapename = 'admin_1_states_provinces'
states_shp = shpreader.natural_earth(resolution='50m', category='cultural', name=shapename)
reader = shpreader.Reader(states_shp)
states = reader.records()

# collect patches of all states of India
state_patches = []
for state in states:
    if state.attributes['admin'] == 'India':
        # show a state on the map only if it is in India
        ax.add_geometries([state.geometry], ccrs.PlateCarree(), edgecolor='k', facecolor='none')
        if isinstance(state.geometry, sg.MultiPolygon):
            # if this state includes a few polygons, process them separately
            polygons = list(state.geometry.geoms)
            for p in polygons:
                # make a patch out of this polygon and store it
                state_patches.append(patches.Polygon(np.array(p.exterior.xy).T))
        else:
            # make a patch out of this polygon and store it
            state_patches.append(patches.Polygon(np.array(state.geometry.exterior.xy).T))

# make a compound path out of vertices and codes of the state patches
vertices = np.concatenate([i.get_path().vertices for i in state_patches])
codes = np.concatenate([i.get_path().codes for i in state_patches])

# clip the filled contour using that compound path
cs.set_clip_path(PathPatch(Path(vertices, codes), transform=ax.transData))

plt.show()

输出结果:

这里插入图片描述

撰写回答