use*_*627 5 3d matplotlib python-2.7 matplotlib-basemap cartopy
我是Python的新手,关于Cartopy能够在3D情节中使用的问题.以下是使用的示例matplotlibBasemap
.
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.basemap import Basemap
m = Basemap(projection='merc',
llcrnrlat=52.0,urcrnrlat=58.0,
llcrnrlon=19.0,urcrnrlon=40.0,
rsphere=6371200.,resolution='h',area_thresh=10)
fig = plt.figure()
ax = Axes3D(fig)
ax.add_collection3d(m.drawcoastlines(linewidth=0.25))
ax.add_collection3d(m.drawcountries(linewidth=0.35))
ax.add_collection3d(m.drawrivers(color='blue'))
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Height')
fig.show()
Run Code Online (Sandbox Code Playgroud)
这将在3D轴内创建一个贴图,以便您可以在曲面上绘制对象.但随着Cartopy回归matplotlib.axes.GeoAxesSubplot
.不清楚如何拍摄并添加到上面的3D图形/轴上matplotlib-basemap
.
那么,有人可以提供有关如何使用Cartopy进行类似3D绘图的任何指示吗?
pel*_*son 10
底图mpl3d是一个非常简洁的黑客,但它没有被设计为以所描述的方式运行.因此,除了简单的海岸线之外,您目前无法使用相同的技术.例如,填补的大陆只是不工作AFAICT.
也就是说,使用cartopy时可以使用类似的hack.由于我们可以一般地访问shapefile信息,因此该解决方案适用于任何多线形状文件,例如海岸线.
第一步是获取shapefile和相应的几何:
feature = cartopy.feature.NaturalEarthFeature('physical', 'coastline', '110m')
geoms = feature.geometries()
Run Code Online (Sandbox Code Playgroud)
接下来,我们可以将这些转换为所需的投影:
target_projection = ccrs.PlateCarree()
geoms = [target_projection.project_geometry(geom, feature.crs)
for geom in geoms]
Run Code Online (Sandbox Code Playgroud)
由于这些是几何形状,我们希望将它们转换为matplotlib路径:
from cartopy.mpl.patch import geos_to_path
import itertools
paths = list(itertools.chain.from_iterable(geos_to_path(geom)
for geom in geoms))
Run Code Online (Sandbox Code Playgroud)
使用路径,我们应该能够在matplotlib中创建一个PathCollection,并将其添加到轴中,但遗憾的是,Axes3D似乎无法处理PathCollection实例,因此我们需要通过构造LineCollection来解决这个问题(如底图一样) ).可悲的是,LineCollections不会采用路径,而是采用我们可以计算的段:
segments = []
for path in paths:
vertices = [vertex for vertex, _ in path.iter_segments()]
vertices = np.asarray(vertices)
segments.append(vertices)
Run Code Online (Sandbox Code Playgroud)
将这些全部拉到一起,我们最终会得到与您的代码生成的底图图类似的结果:
import itertools
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
import numpy as np
import cartopy.feature
from cartopy.mpl.patch import geos_to_path
import cartopy.crs as ccrs
fig = plt.figure()
ax = Axes3D(fig, xlim=[-180, 180], ylim=[-90, 90])
ax.set_zlim(bottom=0)
target_projection = ccrs.PlateCarree()
feature = cartopy.feature.NaturalEarthFeature('physical', 'coastline', '110m')
geoms = feature.geometries()
geoms = [target_projection.project_geometry(geom, feature.crs)
for geom in geoms]
paths = list(itertools.chain.from_iterable(geos_to_path(geom) for geom in geoms))
# At this point, we start working around mpl3d's slightly broken interfaces.
# So we produce a LineCollection rather than a PathCollection.
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')
ax.add_collection3d(lc)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Height')
plt.show()
Run Code Online (Sandbox Code Playgroud)
除此之外,mpl3d似乎很好地处理PolyCollection,这将是我将研究填充几何的路线,例如陆地轮廓(与海岸线相对,严格地说是轮廓).
重要的一步是将路径转换为多边形,并在PolyCollection对象中使用它们:
concat = lambda iterable: list(itertools.chain.from_iterable(iterable))
polys = concat(path.to_polygons() for path in paths)
lc = PolyCollection(polys, edgecolor='black',
facecolor='green', closed=False)
Run Code Online (Sandbox Code Playgroud)
这种情况的完整代码如下所示:
import itertools
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection, PolyCollection
import numpy as np
import cartopy.feature
from cartopy.mpl.patch import geos_to_path
import cartopy.crs as ccrs
fig = plt.figure()
ax = Axes3D(fig, xlim=[-180, 180], ylim=[-90, 90])
ax.set_zlim(bottom=0)
concat = lambda iterable: list(itertools.chain.from_iterable(iterable))
target_projection = ccrs.PlateCarree()
feature = cartopy.feature.NaturalEarthFeature('physical', 'land', '110m')
geoms = feature.geometries()
geoms = [target_projection.project_geometry(geom, feature.crs)
for geom in geoms]
paths = concat(geos_to_path(geom) for geom in geoms)
polys = concat(path.to_polygons() for path in paths)
lc = PolyCollection(polys, edgecolor='black',
facecolor='green', closed=False)
ax.add_collection3d(lc)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Height')
plt.show()
Run Code Online (Sandbox Code Playgroud)
产量:
归档时间: |
|
查看次数: |
2641 次 |
最近记录: |