气象绘图 |
您所在的位置:网站首页 › xlim在r › 气象绘图 |
本节提要:通过collection功能的开发实现图形的迁移。 在前面推送中我们提到了通过collection功能而在3D地图中添加地图的方法,也短暂提到了栅格与填色两种图形样式的降维方法。但是从matplotlib这两个函数的底层有一定的局限性,比如下面这两张图的侧面填色就无法绘出: ![]() ![]() 前一张图只能画最上面的等值线填色和地图,下面这张的栅格也是无法绘制出来的,只能画地图。所以通过相同的collection办法,我们来实现图形的迁移。 一、Axes子图平面pcolormesh的迁移 import matplotlib.pyplot as plt import cartopy.crs as ccrs import cartopy.io.shapereader as spder import numpy as np import itertools from matplotlib.collections import LineCollection, PolyCollection plt.rcParams['font.sans-serif']=['SimHei']#显示中文 plt.rcParams['axes.unicode_minus']=False shp=r'E:\家园\利川市地图\利川.shp' fig=plt.figure(figsize=(4,2)) fig,ax=plt.subplots(ncols=2,subplot_kw={'projection':ccrs.PlateCarree()},dpi=500) for i in range(2): ax[i].add_geometries(spder.Reader(shp).geometries(),crs=ccrs.PlateCarree(),facecolor='none',edgecolor='k') ax[i].set_extent([108.3,109.35,29.7,30.7]) x=np.arange(108.3,109.35,0.05) y=np.arange(29.7,30.7,0.05) lon,lat=np.meshgrid(x,y) data=(lon-(109.35-108.3))**2+(lat-(29.7-30.7))**2 ap=ax[0].pcolormesh(lon,lat,data,cmap='Spectral_r') fc=fig.colorbar(ap,ax=[ax[0],ax[1]],shrink=0.5) fc.ax.tick_params(labelsize=4) datas=data.flatten() paths=ap.get_paths() concat = lambda iterable: list(itertools.chain.from_iterable(iterable)) polys = concat(path.to_polygons() for path in paths) lc=PolyCollection(polys,cmap='Spectral_r',edgecolor='none',closed=False,array=datas) ax[1].add_collection(lc) plt.show()![]() 这一句,在第一张子图上绘制了一个pcolormesh,并将它返回的图形几何省称为ap。 datas=data.flatten() paths=ap.get_paths()前一句对data降维,后一句获取ap的path。 concat = lambda iterable: list(itertools.chain.from_iterable(iterable)) polys = concat(path.to_polygons() for path in paths) lc=PolyCollection(polys, cmap='Spectral_r', edgecolor='none', closed=False, array=datas)变path为polygon再收集为collection和地图的添加步骤类似,唯array这一个参数是用来给polygon上色的。 二、跨越Axes与Axes3D进行collection的迁移 import itertools import pandas as pd from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt from matplotlib.collections import LineCollection, PolyCollection import numpy as np from cartopy.io.shapereader import Reader import cartopy.feature from cartopy.mpl.patch import geos_to_path import cartopy.crs as ccrs import numpy as np ########################################################### proj= ccrs.PlateCarree() plt.rcParams['font.sans-serif']=['FangSong']#正常显示中文 fig = plt.figure(figsize=(8,5),dpi=700) ax = Axes3D(fig, xlim=[108.3,109.35], ylim=[29.7,30.7]) ax.set_zlim(0,50) target_projection = ccrs.PlateCarree() ###################################################################### reader = Reader(r'E:\家园\利川市地图\利川.shp') provinces = cartopy.feature.ShapelyFeature(reader.geometries(), proj, edgecolor='k', facecolor='none') #################################################################### geoms = provinces.geometries() geoms = [target_projection.project_geometry(geom, provinces.crs) for geom in geoms] paths = list(itertools.chain.from_iterable(geos_to_path(geom) for geom in geoms)) segments = [] for path in paths: vertices = [vertex for vertex, _ in path.iter_segments()] vertices = np.asarray(vertices) segments.append(vertices) lc = LineCollection(segments, color='black',lw=1) ax.add_collection3d(lc,zs=50) ax.set_xlabel('经度 (E)') ax.set_ylabel('纬度 (N)') ax.set_zlabel('层次') ax.view_init(elev=35,azim=290)#改变绘制图像的视角,即相机的位置,azim沿着z轴旋转,elev沿着y轴 plt.title('pcolormesh迁移',fontsize=20) ax1=fig.add_axes([0,0,0.5,0.5],projection=ccrs.PlateCarree()) ax1.add_geometries(Reader(r'E:\家园\利川市地图\利川.shp').geometries(),crs=ccrs.PlateCarree(),facecolor='none',edgecolor='k') ax1.set_extent([108.3,109.35,29.7,30.7]) x=np.arange(108.3,109.35,0.05) y=np.arange(29.7,30.7,0.05) lon,lat=np.meshgrid(x,y) data=(lon-(109.35-108.3))**2+(lat-(29.7-30.7))**2 ap=ax1.pcolormesh(lon,lat,data,cmap='Spectral_r') datas=data.flatten() paths=ap.get_paths() concat = lambda iterable: list(itertools.chain.from_iterable(iterable)) polys = concat(path.to_polygons() for path in paths) lc=PolyCollection(polys,cmap='Spectral_r',edgecolor='none',closed=False,array=datas) lc1=PolyCollection(polys,cmap='BuGn_r',edgecolor='none',closed=False,array=datas) lc2=PolyCollection(polys,cmap='viridis',edgecolor='none',closed=False,array=datas) ax.add_collection3d(lc,zs=50) ax.add_collection3d(lc1,zs=25) ax.add_collection3d(lc2,zs=0) ax1.set_visible(False)#解除ax1的显示原本生成的图: ![]() 解除掉用于生成平面pcolormesh的子图的显示后的图: ![]() 三、多层contourf的叠加 import itertools import pandas as pd from scipy.interpolate import Rbf from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt from matplotlib.collections import LineCollection, PolyCollection import numpy as np from cartopy.io.shapereader import Reader import cartopy.feature from cartopy.mpl.patch import geos_to_path import cartopy.crs as ccrs import numpy as np ########################################################### proj= ccrs.PlateCarree() plt.rcParams['font.sans-serif']=['FangSong']#正常显示中文 fig = plt.figure(figsize=(8,5),dpi=700) ax = Axes3D(fig, xlim=[108.3,109.35], ylim=[29.7,30.7]) ax.set_zlim(0,50) target_projection = ccrs.PlateCarree() ###################################################################### reader = Reader(r'E:\家园\利川市地图\利川.shp') provinces = cartopy.feature.ShapelyFeature(reader.geometries(), proj, edgecolor='k', facecolor='none') #################################################################### geoms = provinces.geometries() geoms = [target_projection.project_geometry(geom, provinces.crs) for geom in geoms] paths = list(itertools.chain.from_iterable(geos_to_path(geom) for geom in geoms)) segments = [] for path in paths: vertices = [vertex for vertex, _ in path.iter_segments()] vertices = np.asarray(vertices) segments.append(vertices) lc = LineCollection(segments, color='black',lw=1) ax.add_collection3d(lc,zs=0) ax.set_xlabel('经度 (E)') ax.set_ylabel('纬度 (N)') ax.set_zlabel('层次') ax.view_init(elev=35,azim=290)#改变绘制图像的视角,即相机的位置,azim沿着z轴旋转,elev沿着y轴 plt.title('三维contourf平面化',fontsize=20) ax1=fig.add_axes([0,0,0.5,0.5],projection=ccrs.PlateCarree()) ax1.add_geometries(Reader(r'E:\家园\利川市地图\利川.shp').geometries(),crs=ccrs.PlateCarree(),facecolor='none',edgecolor='k') ax1.set_extent([108.3,109.35,29.7,30.7]) x=np.arange(108.3,109.35,0.05) y=np.arange(29.7,30.7,0.05) lon,lat=np.meshgrid(x,y) data=(lon-(109.35-108.3))**2+(lat-(29.7-30.7))**2 ax.contourf(lon,lat,data,cmap='Spectral_r',offset=50) ax.contourf(lon,lat,data,cmap='BuGn_r',offset=25) ax.contourf(lon,lat,data,cmap='viridis',offset=0) ax1.set_visible(False)![]() 四、Axes的pcolormesh的多面迁移 import itertools import pandas as pd from scipy.interpolate import Rbf from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt from matplotlib.collections import LineCollection, PolyCollection import numpy as np from cartopy.io.shapereader import Reader import cartopy.feature from cartopy.mpl.patch import geos_to_path import cartopy.crs as ccrs import numpy as np ########################################################### proj= ccrs.PlateCarree() concat = lambda iterable: list(itertools.chain.from_iterable(iterable)) plt.rcParams['font.sans-serif']=['FangSong']#正常显示中文 plt.rcParams['axes.unicode_minus']=False fig = plt.figure(figsize=(8,5),dpi=700) ax = Axes3D(fig, xlim=[-50,50], ylim=[-50,50]) ax.set_zlim(-50,50) ax.set(xticks=np.arange(-50,60,25),yticks=np.arange(-50,60,25),zticks=np.arange(-50,60,25)) ax2=fig.add_axes([0,0,0.5,0.5]) x=np.arange(-50,55,5) y=np.arange(-50,55,5) x,y=np.meshgrid(x,y) z=x**2+y**2 a2=ax2.pcolormesh(x,y,z,shading='auto') ################################################################## zs=z.flatten() paths2=a2.get_paths() polys2 =concat(path.to_polygons() for path in paths2) lc02=PolyCollection(polys2,cmap='Spectral_r',edgecolor='none',closed=False,array=zs) lc03=PolyCollection(polys2,cmap='Greys',edgecolor='none',closed=False,array=zs) lc04=PolyCollection(polys2,cmap='BuGn',edgecolor='none',closed=False,array=zs) ax.add_collection3d(lc02,zdir='y',zs=-51) ax.add_collection3d(lc03,zdir='x',zs=51) ax.add_collection3d(lc04,zdir='z',zs=51) ax2.set_visible(False) ax.set_title('立方pcolocmesh',fontsize=17,pad=-100000000)![]() 通过修改zdir来实现各个面的贴瓷砖。 五、Axes的contourf多面迁移 import itertools import pandas as pd from scipy.interpolate import Rbf from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt from matplotlib.collections import LineCollection, PolyCollection from mpl_toolkits.mplot3d.art3d import Poly3DCollection import numpy as np from cartopy.io.shapereader import Reader import cartopy.feature from cartopy.mpl.patch import geos_to_path import cartopy.crs as ccrs import numpy as np ########################################################### proj= ccrs.PlateCarree() concat = lambda iterable: list(itertools.chain.from_iterable(iterable)) plt.rcParams['font.sans-serif']=['FangSong']#正常显示中文 plt.rcParams['axes.unicode_minus']=False fig = plt.figure(figsize=(8,5),dpi=700) ax = Axes3D(fig, xlim=[-50,50], ylim=[-50,50]) ax.set_zlim(-50,50) ax.set(xticks=np.arange(-50,60,25),yticks=np.arange(-50,60,25),zticks=np.arange(-50,60,25)) ax2=fig.add_axes([0,0,0.5,0.5]) x=np.arange(-50,55,5) y=np.arange(-50,55,5) x,y=np.meshgrid(x,y) z=x+np.sin(x)-y-np.tan(y) cs=ax2.contourf(x,y,z) ################################################################## for level,collection in zip(cs.levels,cs.collections): paths=collection.get_paths() polys=concat(path.to_polygons() for path in paths) pc=PolyCollection(polys,facecolor=collection.get_facecolor(),edgecolor='none') ax.add_collection3d(pc,zdir='z',zs=50) for level,collection in zip(cs.levels,cs.collections): paths=collection.get_paths() polys=concat(path.to_polygons() for path in paths) pc=PolyCollection(polys,facecolor=collection.get_facecolor(),edgecolor='none') ax.add_collection3d(pc,zdir='x',zs=50) for level,collection in zip(cs.levels,cs.collections): paths=collection.get_paths() polys=concat(path.to_polygons() for path in paths) pc=PolyCollection(polys,facecolor=collection.get_facecolor(),edgecolor='none') ax.add_collection3d(pc,zdir='y',zs=-50) ax2.set_visible(False)![]() 但是这个办法有个问题,如果有封闭的polygon则会添加不出来,还没有找到适合的方法来解决这个问题,如果有大神希望能指导一二: ![]() 六、仿制一张图 ![]() |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |