| 
 
	积分478贡献 精华在线时间 小时注册时间2019-9-2最后登录1970-1-1 
 | 
 
| 
本帖最后由 饕餮之影 于 2020-5-27 11:41 编辑
x
登录后查看更多精彩内容~您需要 登录 才可以下载或查看,没有帐号?立即注册 
  
 最近对画的EC图做裁剪,根据中国区域的shp文件裁剪中国区域的,遇到点问题记录一下:
 def clip_region(sf, ax):
 
 for shape_rec in sf.shapeRecords():
 vertices = []
 codes = []
 pts = shape_rec.shape.points
 prt = list(shape_rec.shape.parts) + [len(pts)]
 for i in range(len(prt) - 1):
 for j in range(prt, prt[i + 1]):
 vertices.append((pts[j][0], pts[j][1]))
 codes += [ mpl.path.Path.MOVETO]
 codes += [ mpl.path.Path.LINETO] * (prt[i + 1] - prt - 2)
 codes += [ mpl.path.Path.CLOSEPOLY]
 clip = mpl.path.Path(vertices, codes)
 clip = mpl.patches.PathPatch(clip, transform=ax.transData)
 
 return clip, vertices
 
 wind_clevs  = [0.01, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 100]
 wind_colors = ["#FFFFF0", "#F0F4D2", "#E9F49F", "#ABCF63", "#E3EE0F", "#FFEE00", "#FFEE83", "#F4D280","#EEA647", "#E68D3B", "#DC7D3B", "#F0013B", "#E955A4", "#9C70A9", "#6370F7", "#8097FF", "#8FB4FF", "#B7CAFF"]
 
 U = np.random.randint(30, size=(481, 721))
 V = np.random.randint(30, size=(481, 721))
 
 fig = plt.figure(figsize=(16, 8))
 ax  = fig.add_axes([0.1, 0.1, 0.7, 0.7])
 map = Basemap(projection='cyl',
 llcrnrlon=60,
 llcrnrlat=0,
 urcrnrlon=150,
 urcrnrlat=60)
 
 map.drawcoastlines()    # 绘制海岸线
 map.drawcountries()     # 绘制国界
 parallels = np.arange(0.,60,10.)
 map.drawparallels(parallels,labels=[1,0,0,0],fontsize=10) # 绘制纬线
 
 meridians = np.arange(60.,150.,10.)
 map.drawmeridians(meridians,labels=[0,0,0,1],fontsize=10) # 绘制经线
 
 cmap = mpl.colors.ListedColormap(wind_colors)
 norm = mpl.colors.BoundaryNorm(wind_clevs, ncolors=cmap.N, clip=False)
 
 lats = np.arange(0, 60.125, 0.125)[::-1]
 lons = np.arange(60, 150.125,0.125)
 x, y = np.meshgrid(lons, lats)
 
 wind_10m = np.sqrt(U**2 + V**2)
 im = plt.contourf(x, y, wind_10m, norm=norm, cmap=cmap, alpha=1)
 sf = shapefile.Reader(shpname + '.shp', encoding='ISO-8859-1')
 clip, vertices = clip_region(sf, ax)
 
 for cour in im.collections:
 cour.set_clip_path(clip)
 
 for x in plt.gca().get_children():
 if type(x) == mpl.patches.FancyArrowPatch:
 x.set_clip_path(clip)
 
 fig.colorbar(strm.lines)
 plt.show()
 
 画图使用的数据是随机产生的,画图是使用contourf,裁剪前后的图片:
 使用contour画等高线是一样的。这个比较好操作网上可以查询,但是我使用streamplot画流线图出现了剪裁问题:
 strm = plt.streamplot(x, y, U, V, color=U, linewidth=1, cmap=cmap, norm=norm, arrowsize=1)
 这个返回有两个对象是strm.lines和strm.arrows,是保存线和箭头的,
 
 使用strm.lines.set_clip_path(clip),strm.arrows.set_clip_path(clip)裁剪之后:
 线条被裁了但是箭头还存在,查看连个对象返回的路径,get_paths()发现两个的坐标系不一样,lines是CompositeGenericTransform(复合转换),arrows是IdentityTransform(原地转换),我以为是这个问题导致的,于是在clip_region中收集区域边界点的时候 vertices.append(ax.transData.transform(pts[j][0], pts[j][1])),还是没有效果,后来搜到发现箭头是属于
 matplotlib.patches.FancyArrowPatch,无论怎么对strm.arrows操作都没有效果,我们可以使用另一个方法
 for x in gca().get_children():    if type(x) == matplotlib.patches.FancyArrowPatch:        x.set_clip_path(clip)
 这样就可以达到效果了,结果图:
 
 
 
 
 | 
 
contourf裁剪之后的   
streamplot裁剪之前的   
contourf裁剪之前的   
streamplot裁剪   
streamplot裁剪之后的   |