Python 如何为底图多边形使用“设置剪裁路径”

Python 如何为底图多边形使用“设置剪裁路径”,python,matplotlib,gis,shapefile,matplotlib-basemap,Python,Matplotlib,Gis,Shapefile,Matplotlib Basemap,我想使用imshow(例如)显示国家边界内的一些数据(出于示例目的,我选择了美国)。下面的简单示例说明了我想要的: import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import RegularPolygon data = np.arange(100).reshape(10, 10) fig = plt.figure() ax = fig.add_subplot(111) im = ax.ims

我想使用imshow(例如)显示国家边界内的一些数据(出于示例目的,我选择了美国)。下面的简单示例说明了我想要的:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import RegularPolygon

data = np.arange(100).reshape(10, 10)
fig = plt.figure()
ax = fig.add_subplot(111)
im = ax.imshow(data)
poly = RegularPolygon([ 0.5,  0.5], 6, 0.4, fc='none', 
                      ec='k', transform=ax.transAxes)
im.set_clip_path(poly)
ax.add_patch(poly)
ax.axis('off')
plt.show()
结果是:

现在我想这样做,但不是简单的多边形,我想使用美国的复杂形状。我创建了一些包含在“Z”数组中的示例数据,如下面的代码所示。我想用彩色地图显示这些数据,但只能显示在美国大陆的边界内

到目前为止,我已经尝试了以下方法。我从“nationp010g.shp.tar.gz”中获得一个形状文件,并使用python中的Basemap模块绘制美国。请注意,这是我找到的唯一一种方法,它使我能够获得所需区域的多边形。如果有其他方法,我也会对它们感兴趣。然后,我创建了一个名为“mainpoly”的多边形,它几乎就是我想要的蓝色多边形:

请注意,只有一个实体已着色,所有其他不相交多边形仍保持白色:

所以蓝色区域几乎就是我想要的,注意加拿大附近有不需要的边界线,因为边界实际上穿过一些湖泊,但这是一个小问题。真正的问题是,为什么我的imshow数据不显示在美国境内?比较我的第一个和第二个示例代码,我不明白为什么我在第二个示例中没有像第一个示例中那样得到一个剪辑的imshow。如果您能帮助我了解我所缺少的东西,我们将不胜感激

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap as Basemap
from matplotlib.patches import Polygon

# Lambert Conformal map of lower 48 states.
m = Basemap(llcrnrlon=-119,llcrnrlat=22,urcrnrlon=-64,urcrnrlat=49,
            projection='lcc',lat_1=33,lat_2=45,lon_0=-95)


shp_info = m.readshapefile('nationp010g/nationp010g', 'borders', drawbounds=True) # draw     country boundaries.

for nshape,seg in enumerate(m.borders):
    if nshape == 1873: #This nshape denotes the large continental body of the USA, which we want
        mainseg = seg
        mainpoly =  Polygon(mainseg,facecolor='blue',edgecolor='k')



nx, ny = 10, 10
lons, lats = m.makegrid(nx, ny) # get lat/lons of ny by nx evenly space grid.
x, y = m(lons, lats) # compute map proj coordinates.

Z = np.zeros((nx,ny))
Z[:] = np.NAN

for i in np.arange(len(x)):
    for j in np.arange(len(y)):
        Z[i,j] = x[0,i] 

ax = plt.gca()
im = ax.imshow(Z, cmap = plt.get_cmap('coolwarm') )
im.set_clip_path(mainpoly)
ax.add_patch(mainpoly)
plt.show()
更新 我意识到这条线

ax.add_patch(mainpoly)
甚至不会将多边形形状添加到绘图中。我用得不对吗?据我所知,mainpoly是使用Polygon()方法正确计算的。我检查了坐标输入是否合理:

plt.plot(mainseg[:,0], mainseg[:,1] ,'.') 


关于这个问题,我也考虑了很久。
我发现NCL语言具有屏蔽某些边界之外的数据的功能。
以下是一个例子:

轮廓图仅显示在中国境内。点击查看代码

我知道python有一个名为PyNCL的包,它支持python框架中的所有NCL代码。
但我真的想用basemap绘制这种图形。如果你已经弄明白了,请在网上发布。我会在第一时间学习的

谢谢

添加2016-01-16 在某种程度上,我已经弄明白了。
这是我的想法和代码,它的灵感来自我今天提出的这个问题

我的方法:
1.将感兴趣区域的形状文件(如U.S)做成形状优美的多边形。
2.测试多边形内外的每个值点。
3.如果值点不在研究区域内,则将其屏蔽为np.nan

介绍 *多边形xxx是ESRI shapefile格式的中国城市。 *菲奥娜,Saby包在这里使用。
# generate the shapely.polygon
shape = fiona.open("xxx.shp")
pol = shape.next()
geom = shape(pol['geometry'])
poly_data = pol["geometry"]["coordinates"][0]
poly = Polygon(poly_data)
它显示如下:

结果

原始结果

我也很好奇,为什么我会落选。请告诉我,这样我才能提高!你试过什么?你在问什么?问题真的是“如何简化路径?”?如果是这样的话,为什么路径与美国有关?您看过任何几何图形库吗?大概你想靠近切萨皮克湾,也许是长岛湾,但不是墨西哥湾。这个问题是超级开放的,没有显示出太多的研究成果,读起来是“请为我做我的工作,给我一个代码!”!!1!' 对于愤世嫉俗/暴躁/厌倦的SO成员。好的,我会更新一些信息,谢谢。请查看我更新的问题。这更好。谢谢-我承认我有一段时间没有看这个,但如果有什么事情发生,我会让你知道。太好了。我也要试试。
### test the value point 
### generate the grid network which represented by the grid midpoints.
lon_med  = np.linspace((xi[0:2].mean()),(xi[-2:].mean()),len(x_grid))
lat_med  = np.linspace((yi[0:2].mean()),(yi[-2:].mean()),len(y_grid))

value_test_mean = dsu.mean(axis = 0)
value_mask =  np.zeros(len(lon_med)*len(lat_med)).reshape(len(lat_med),len(lon_med))
for i in range(0,len(lat_med),1):
    for j in range(0,len(lon_med),1):
        points = np.array([lon_med[j],lat_med[i]])
        mask = np.array([poly.contains(Point(points[0], points[1]))])
        if mask == False:
            value_mask[i,j] = np.nan
        if mask == True:
            value_mask[i,j] = value_test_mean[i,j]


# Mask the np.nan value 
Z_mask = np.ma.masked_where(np.isnan(so2_mask),so2_mask)

# plot!
fig=plt.figure(figsize=(6,4))
ax=plt.subplot()

map = Basemap(llcrnrlon=x_map1,llcrnrlat=y_map1,urcrnrlon=x_map2,urcrnrlat=y_map2)
map.drawparallels(np.arange(y_map1+0.1035,y_map2,0.2),labels=  [1,0,0,1],size=14,linewidth=0,color= '#FFFFFF')
lon_grid  = np.linspace(x_map1,x_map2,len(x_grid))
lat_grid  = np.linspace(y_map1,y_map2,len(y_grid))
xx,yy = np.meshgrid(lon_grid,lat_grid)
pcol =plt.pcolor(xx,yy,Z_mask,cmap = plt.cm.Spectral_r ,alpha =0.75,zorder =2)