前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Basemap系列教程:3D

Basemap系列教程:3D

作者头像
bugsuse
发布2020-04-21 17:46:45
1.3K0
发布2020-04-21 17:46:45
举报
文章被收录于专栏:气象杂货铺气象杂货铺

尽管很多人不喜欢3D地图,但是仍可以使用 Basemap 和 matplotlib mplot3d [注1] 工具绘制3D地图。

创建基本地图

当使用 matplotlib 绘制3D图时,最重要的一点是,要使用 Axes3D 类。使用 add_collection3d 可以添加地理数据到地图中。

代码语言:javascript
复制
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.basemap import Basemap

map = Basemap()

fig = plt.figure()
ax = Axes3D(fig)

'''
ax.azim = 270
ax.elev = 90
ax.dist = 5
'''

ax.add_collection3d(map.drawcoastlines(linewidth=0.25))
ax.add_collection3d(map.drawcountries(linewidth=0.35))

plt.show()
  • 此例中 ax 是 Axes3D 实例变量。使用的所有方法都源自此实例,因此需要支持 3D 操作。对于 basemap 方法来说,大多数情况下都不支持。
  • 注释部分显示了如何旋转地图以获得更好的视图
  • 要绘制海岸线,可将 basemap方法的结果作为参数传递给 add_collection3d 方法

基本用法。轴的旋转是默认的

轴的旋转设置为由 z 轴向下看,看起来就像是 2D图形

填充多边形

不幸的是, basemap 的 fillcontinents 方法不能返回 add_collection3d 支持的对象(PolyCollection, LineColleciton, PatchCollection),而是 matplotlib.patches.Polygon 对象列表。

解决办法就是创建 PolyCollection 对象。

代码语言:javascript
复制
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.basemap import Basemap
from matplotlib.collections import PolyCollection

map = Basemap()

fig = plt.figure()
ax = Axes3D(fig)

ax.azim = 270
ax.elev = 50
ax.dist = 8

ax.add_collection3d(map.drawcoastlines(linewidth=0.25))
ax.add_collection3d(map.drawcountries(linewidth=0.35))

polys = []
for polygon in map.landpolygons:
    polys.append(polygon.get_coords())


lc = PolyCollection(polys, edgecolor='black',
                    facecolor='#DDDDDD', closed=False)

ax.add_collection3d(lc)


plt.show()
  • 要创建 PolyCollection 就需要 polygons,而在 Basemap 对象的 landpolygons 域中就存在 polygons
  • 对于每一个 polygons 来说, 使用 get_coords 方法可以提取一系列浮点坐标
  • 一旦坐标列表创建了,那么就可以创建 PoilyCollection
  • 使用 add_collection3d 添加 PolyCollection
  • 如果使用 fillcontinents 添加 polygon, matplotlib 没有任何方法可以将其转换为 3D

添加3D 条形图

如果没有添加数据到地图上,那么绘制3D地图将没有任何意义。 Axes3D 类有 bar3d 方法用于绘制 3D 条形图。

代码语言:javascript
复制
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.basemap import Basemap
from matplotlib.collections import PolyCollection
import numpy as np

map = Basemap(llcrnrlon=-20,llcrnrlat=0,urcrnrlon=15,urcrnrlat=50,)

fig = plt.figure()
ax = Axes3D(fig)

ax.set_axis_off()
ax.azim = 270
ax.dist = 7

polys = []
for polygon in map.landpolygons:
    polys.append(polygon.get_coords())


lc = PolyCollection(polys, edgecolor='black',
                    facecolor='#DDDDDD', closed=False)

ax.add_collection3d(lc)
ax.add_collection3d(map.drawcoastlines(linewidth=0.25))
ax.add_collection3d(map.drawcountries(linewidth=0.35))

lons = np.array([-13.7, -10.8, -13.2, -96.8, -7.99, 7.5, -17.3, -3.7])
lats = np.array([9.6, 6.3, 8.5, 32.7, 12.5, 8.9, 14.7, 40.39])
cases = np.array([1971, 7069, 6073, 4, 6, 20, 1, 1])
deaths = np.array([1192, 2964, 1250, 1, 5, 8, 0, 0])
places = np.array(['Guinea', 'Liberia', 'Sierra Leone','United States', 'Mali', 'Nigeria', 'Senegal', 'Spain'])

x, y = map(lons, lats)

ax.bar3d(x, y, np.zeros(len(x)), 2, 2, deaths, color= 'r', alpha=0.8)

plt.show()
  • 放大地图以适应 Ebola 数据集
  • 使用 set_axis_off 方法去除 axis
  • bar3d 需要 x,y 和 z 的位置,加上 delta x,y,z。为了合适的绘制图形,z 必须是0,而 delta z 就是最终的数据值

注1:http://matplotlib.org/mpl_toolkits/mplot3d/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 气象杂货铺 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图像处理
图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档