数据科学中,常用的一种可视化类型是地理图像的绘制,Matplotlib中绘制这一类型图像的是BaseMap库,它是在mpl_toolkits下的Matplotlib工具库之一。相比于现在常用的其它绘图工具,如leaflet, Google Maps API, BaseMap略显笨重,但在Python中,它还是非常有效的地图绘制工具,本章我们将讲解下如果用BaseMap进行地理图像的绘制。
BaseMap安装比较简单,可以通过conda直接安装或者下载按照,如果安装过程中出现一些问题,可参照我另一篇文章《Basemap报错KeyError: 'PROJ_LIB'》寻找解决办法。
$ conda install basemap
该模块的标准引用:
%matplotlib inlineimport numpy as npimport matplotlib.pyplot as pltfrom mpl_toolkits.basemap import Basemap
工具库添加后便可以开始地图的绘制,如绘制一个地球表面图像:
plt.figure(figsize = (8,8))m = Basemap(projection = 'ortho',resolution = None, lat_0=50, lon_0 = -100)m.bluemarble(scale=0.5)
A "bluemarble" projection of the Earth
里面参数的含义我们稍后讨论。
在BaseMap中,绘制出的图像不仅仅是一个图片,它是带有地理坐标的,这意味着我们可以在图像上作数据标注。例如我们可以绘制出一张北美的地图,然后在上面标注出西雅图(Seattle)的位置。此处我们选择一种etopo的图像(含陆地和海洋背景的一种图像)。
fig = plt.figure(figsize=(8, 8)) m = Basemap(projection='lcc', resolution=None, width=8E6, height=8E6, lat_0=45, lon_0=-100,) m.etopo(scale=0.5, alpha=0.5) # 经纬度输入 (long, lat) to (x, y) x, y = m(-122.3, 47.6) plt.plot(x, y, 'ok', markersize=5) plt.text(x, y, ' Seattle', fontsize=12);
地图标注图像
此处仅给出了地理可视化的两个简单示例,简单几行代码,可实现地图的可视化绘制,下面我们深入介绍下BaseMap库,通过下面几个例子,你将能够学会如何创建你想要的地理图像。
选择Map Projection
绘制图像第一件事是选择采用哪种projection,我们都知道无法在一个平面上画出一个球形图,如果不对这个球形进行展开,在人类的历史上,已经有发展出一些为人熟知的地理图像,这些通常就是一个个的projection。取决于我们使用地图的目的,我们有大量的projection去选择,此处我选择几个常见的进行介绍,我们首先定义一个绘制世界地图的函数:
from itertools import chaindef draw_map(m, scale=0.2):# 画一个地貌图 m.shadedrelief(scale=scale) # 创建经纬度字典 lats = m.drawparallels(np.linspace(-90, 90, 13)) lons = m.drawmeridians(np.linspace(-180, 180, 13)) # keys contain the plt.Line2D instances lat_lines = chain(*(tup[1][0] for tup in lats.items())) lon_lines = chain(*(tup[1][0] for tup in lons.items())) all_lines = chain(lat_lines, lon_lines) # cycle through these lines and set the desired style for line in all_lines: line.set(linestyle='-', alpha=0.3, color='w')
- Cylindrical projections
Cylindrical projections几乎是最简单的projection,经纬度分别绘制成横线和垂直线,这种图形对于赤道附近的地区表现形式非常好,但对应极点附近的区域,表现就极端扭曲,因为纬线间的空间距离在不同的纬度上是不同的,所以扭曲程度也是不同的。下面是cylindrical projection的一个示例,我们选择等距的cylindrical projections(projection='cyl')),其它还有“merc”和“cea”,可自行尝试。
fig = plt.figure(figsize=(8, 6), edgecolor='w') m = Basemap(projection='cyl', resolution=None,draw_map(m)
Cylindrical equal-area projection
- Pseudo-cylindrical projections
Pseudo-cylindrical projections解决了上图在极点附近图像扭曲的现象,仅在赤道附近纬线是垂直的。Mollweide projection (projection='moll')是常用的一种,它可以是几点附件的图像显示与实际一致的面积大小。其它的有Pseudo-cylindrical projections还有sinusoidal (projection='sinu') 和 Robinson (projection='robin') 。
fig = plt.figure(figsize=(8, 6), edgecolor='w') m = Basemap(projection='moll', resolution=None, lat_0=0, lon_0=0)draw_map(m)
The Molleweide projection
- Perspective projections
Perspective projections是为了查看某一特定视角而采用的一种方式,如同你想在空间的某个视角拍摄地球。常用的一种是orthographic projection (projection='ortho'),它显示的是地球的一面,其它的有gnomonic (projection='gnom') 和 stereographic (projection='stere')。
fig = plt.figure(figsize=(8, 8)) m = Basemap(projection='ortho', resolution=None, lat_0=50, lon_0=0) draw_map(m);
The orthographic projection
- Conic projections
Conic projections展示的是一个圆锥形,它能非常好地展示局部特征,但越远离圆锥,图像扭曲会越严重。Lambert conformal conic projection (projection='lcc'),这个是我们开篇用到的绘制北美的projection,其它的有equidistant conic (projection='eqdc') 和 Albers equal-area (pro jection='aea')。
fig = plt.figure(figsize=(8, 8)) m = Basemap(projection='lcc', resolution=None, lon_0=0, lat_0=50, lat_1=45, lat_2=55, width=1.6E7, height=1.2E7)draw_map(m)
The Albers equal-area projection
- 其它projections
如果你想做地图可视化相关的工作,强烈建议你详细了解各种projections,包括它们的特性,优缺点等。