说了这么久,也看了这么多例子了。这一次我们看一下一些绘图命令。
annotate
创建含有箭头的文本以表示感兴趣的点。要创建无箭头的文本,可使用text。
annotate(*args, **kwargs)
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
map = Basemap(projection='ortho', lat_0=0, lon_0=0)
map.drawmapboundary(fill_color='aqua')
map.fillcontinents(color='coral',lake_color='aqua')
map.drawcoastlines()
x, y = map(2, 41)
x2, y2 = (-90, 10)
plt.annotate('Barcelona', xy=(x, y), xycoords='data', xytext=(x2, y2), textcoords='offset points', color='r', arrowprops=dict(arrowstyle="fancy", color='g'))
x2, y2 = map(0, 0)
plt.annotate('Barcelona', xy=(x, y), xycoords='data', xytext=(x2, y2), textcoords='data', arrowprops=dict(arrowstyle="->"))
plt.show()
在地图中绘制风杆
barbs(x, y, u, v, *args, **kwargs)
关于 barb 的详细说明可以查看 matplotlib 文档。[注1]
同时还有很多其它可选参数 [注3]。一些常用参数如下:
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from osgeo import gdal
import numpy as np
map = Basemap(llcrnrlon=-93.7, llcrnrlat=28., urcrnrlon=-66.1, urcrnrlat=39.5,
projection='lcc', lat_1=30., lat_2=60., lat_0=34.83158, lon_0=-98.)
ds = gdal.Open("../sample_files/wrf.tiff")
lons = ds.GetRasterBand(4).ReadAsArray()
lats = ds.GetRasterBand(5).ReadAsArray()
u10 = ds.GetRasterBand(1).ReadAsArray()
v10 = ds.GetRasterBand(2).ReadAsArray()
x, y = map(lons, lats)
yy = np.arange(0, y.shape[0], 4)
xx = np.arange(0, x.shape[1], 4)
points = np.meshgrid(yy, xx)
map.drawmapboundary(fill_color='aqua')
map.fillcontinents(color='#cc9955', lake_color='aqua', zorder = 0)
map.drawcoastlines(color = '0.15')
map.barbs(x[points], y[points], u10[points], v10[points],
pivot='middle', barbcolor='#333333')
plt.show()
contour
创建等值线图
contour(x, y, data)
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from osgeo import gdal
from numpy import linspace
from numpy import meshgrid
map = Basemap(projection='tmerc',
lat_0=0, lon_0=3,
llcrnrlon=1.819757266426611,
llcrnrlat=41.583851612359275,
urcrnrlon=1.841589961763497,
urcrnrlat=41.598674173123)
ds = gdal.Open("../sample_files/dem.tiff")
data = ds.ReadAsArray()
x = linspace(0, map.urcrnrx, data.shape[1])
y = linspace(0, map.urcrnry, data.shape[0])
xx, yy = meshgrid(x, y)
map.contour(xx, yy, data)
plt.show()
创建填充等值线图
contourf(x, y, data)
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from osgeo import gdal
from numpy import linspace
from numpy import meshgrid
map = Basemap(projection='tmerc',
lat_0=0, lon_0=3,
llcrnrlon=1.819757266426611,
llcrnrlat=41.583851612359275,
urcrnrlon=1.841589961763497,
urcrnrlat=41.598674173123)
ds = gdal.Open("../sample_files/dem.tiff")
data = ds.ReadAsArray()
x = linspace(0, map.urcrnrx, data.shape[1])
y = linspace(0, map.urcrnry, data.shape[0])
xx, yy = meshgrid(x, y)
map.contourf(xx, yy, data)
plt.show()
hexbin
由点集绘制六角箱。可以绘制每一个六边形出现的次数,或是给出每一次出现的权重。
hexbin(x, y, **kwargs)
更多的信息可以查看官方文档。[注6]
注意: 旧版本的库不支持 hexbin
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import matplotlib.colors as colors
from numpy import array
from numpy import max
map = Basemap(llcrnrlon=-0.5,llcrnrlat=39.8,urcrnrlon=4.,urcrnrlat=43.,
resolution='i', projection='tmerc', lat_0 = 39.5, lon_0 = 1)
map.readshapefile('../sample_files/lightnings', 'lightnings')
x = []
y = []
c = []
for info, lightning in zip(map.lightnings_info, map.lightnings):
x.append(lightning[0])
y.append(lightning[1])
if float(info['amplitude']) < 0:
c.append(-1 * float(info['amplitude']))
else:
c.append(float(info['amplitude']))
plt.figure(0)
map.drawcoastlines()
map.readshapefile('../sample_files/comarques', 'comarques')
map.hexbin(array(x), array(y))
map.colorbar(location='bottom')
plt.figure(1)
map.drawcoastlines()
map.readshapefile('../sample_files/comarques', 'comarques')
map.hexbin(array(x), array(y), gridsize=20, mincnt=1, cmap='summer', bins='log')
map.colorbar(location='bottom', format='%.1f', label='log(# lightnings)')
plt.figure(2)
map.drawcoastlines()
map.readshapefile('../sample_files/comarques', 'comarques')
map.hexbin(array(x), array(y), gridsize=20, mincnt=1, cmap='summer', norm=colors.LogNorm())
cb = map.colorbar(location='bottom', format='%d', label='# lightnings')
cb.set_ticks([1, 5, 10, 15, 20, 25, 30])
cb.set_ticklabels([1, 5, 10, 15, 20, 25, 30])
plt.figure(3)
map.drawcoastlines()
map.readshapefile('../sample_files/comarques', 'comarques')
map.hexbin(array(x), array(y), C = array(c), reduce_C_function = max, gridsize=20, mincnt=1, cmap='YlOrBr', linewidths=0.5, edgecolors='k')
map.colorbar(location='bottom', label='Mean amplitude (kA)')
plt.show()
(1) reduce_C_function 参数用于显示每一个 bin 的最大值,从而代替平均值
(2) linewidths 和 edgecolors 使每一个六边形的边界被绘制
基本用法
对数刻度,使用不同的 hexagon 大小
对数刻度,具有更合适的colorbar
使用 C 参数,并且绘制六边形边界
在地图上绘制图像。图像可以是常规的 rgb 图,也可以是用 cmap 填充的图。
imshow(*args, **kwargs)
详细文档可查看 matplotlib 官方文档。[注8]
第一个例子显示了使用 jpg 图像和一个域作为伪彩色图像:
from mpl_toolkits.basemap import Basemap
from mpl_toolkits.basemap import shiftgrid
import matplotlib.pyplot as plt
from osgeo import gdal
import numpy as np
map = Basemap(projection='tmerc',
lat_0=0, lon_0=3,
llcrnrlon=1.819757266426611,
llcrnrlat=41.583851612359275,
urcrnrlon=1.841589961763497,
urcrnrlat=41.598674173123)
ds = gdal.Open("../sample_files/dem.tiff")
elevation = ds.ReadAsArray()
map.imshow(plt.imread('../sample_files/orthophoto.jpg'))
map.imshow(elevation, cmap = plt.get_cmap('terrain'), alpha = 0.5)
plt.show()
第二个例子展示了如何直接在地图上或是在新建的轴上添加 logo:
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
fig = plt.figure()
map = Basemap(projection='ortho',
lat_0=0, lon_0=0)
map.drawlsmask(land_color = "#ddaa66",
ocean_color="#7777ff",
resolution = 'l')
x0, y0 = map(1., 31.)
x1, y1 = map(15., 39.)
plt.imshow(plt.imread('../sample_files/by.png'), extent = (x0, x1, y0, y1))
axicon = fig.add_axes([0.1, 0., 0.15, 0.15])
axicon.imshow(plt.imread('../sample_files/by.png'), origin = 'upper')
axicon.set_xticks([])
axicon.set_yticks([])
plt.show()
1)轴名为 axicon 的轴被创建,分别确定了轴的 x,y 位置及 width 和 height。这些仅是图形尺寸的一部分。
2) 图形被绘制,同时设置 origin 参数,以防止图像上下颠倒
3) xtick 和 ytick 被设置为 null, 因此 logo 中并未显示
我从以下例子中学习到了这些。[注8]
此函数的行为和 pcolormesh 几乎完全相同。
创建伪彩色图
pcolormesh(x, y, data, *args, **kwargs)
见 Basemap 系列教程:基本函数 绘制栅格数据 部分
在地图上绘制 marker 或 lines。
plot(x, y, *args, **kwargs)
第一个例子展示了单个点:
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
map = Basemap(projection='ortho',
lat_0=0, lon_0=0)
map.drawmapboundary(fill_color='aqua')
map.fillcontinents(color='coral',lake_color='aqua')
map.drawcoastlines()
x, y = map(0, 0)
map.plot(x, y, marker='D',color='m')
plt.show()
第二个例子:如果参数是一个数组,那么输出将是一条线(此例中没有 marker)
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
map = Basemap(projection='ortho',
lat_0=0, lon_0=0)
map.drawmapboundary(fill_color='aqua')
map.fillcontinents(color='coral',lake_color='aqua')
map.drawcoastlines()
lons = [-10, -20, -25, -10, 0, 10]
lats = [40, 30, 10, 0, 0, -5]
x, y = map(lons, lats)
map.plot(x, y, marker=None,color='m')
plt.show()
绘制向量场。类似 barbs 方法。
quiver(x, y, u, v, *args, **kwargs)
matplotlib 中的文档介绍更加详细。[注11]
同时还有很多其它可选参数 [注3]。一些常用参数如下:
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from osgeo import gdal
import numpy as np
map = Basemap(llcrnrlon=-93.7, llcrnrlat=28., urcrnrlon=-66.1, urcrnrlat=39.5,
projection='lcc', lat_1=30., lat_2=60., lat_0=34.83158, lon_0=-98.)
ds = gdal.Open("../sample_files/wrf.tiff")
lons = ds.GetRasterBand(4).ReadAsArray()
lats = ds.GetRasterBand(5).ReadAsArray()
u10 = ds.GetRasterBand(1).ReadAsArray()
v10 = ds.GetRasterBand(2).ReadAsArray()
speed = np.sqrt(u10*u10 + v10*v10)
x, y = map(lons, lats)
yy = np.arange(0, y.shape[0], 4)
xx = np.arange(0, x.shape[1], 4)
points = np.meshgrid(yy, xx)
map.drawmapboundary(fill_color='aqua')
map.fillcontinents(color='#cc9955', lake_color='aqua', zorder = 0)
map.drawcoastlines(color = '0.15')
map.quiver(x[points], y[points],
u10[points], v10[points], speed[points],
cmap=plt.cm.autumn)
plt.show()
在地图上绘制多个 marker
scatter(x, y, *args, **kwargs)
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
map = Basemap(projection='ortho',
lat_0=0, lon_0=0)
map.drawmapboundary(fill_color='aqua')
map.fillcontinents(color='coral',lake_color='aqua')
map.drawcoastlines()
lons = [0, 10, -20, -20]
lats = [0, -10, 40, -20]
x, y = map(lons, lats)
map.scatter(x, y, marker='D',color='m')
plt.show()
从向量场绘制流线图。
streamplot(x, y, u, v, *args, **kwargs)
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from osgeo import gdal
import numpy
map = Basemap(llcrnrlon=-93.7, llcrnrlat=28., urcrnrlon=-66.1, urcrnrlat=39.5,
projection='lcc', lat_1=30., lat_2=60., lat_0=34.83158, lon_0=-98.)
ds = gdal.Open("../sample_files/wrf.tiff")
lons = ds.GetRasterBand(4).ReadAsArray()
lats = ds.GetRasterBand(5).ReadAsArray()
u10 = ds.GetRasterBand(1).ReadAsArray()
v10 = ds.GetRasterBand(2).ReadAsArray()
speed = numpy.sqrt(u10*u10 + v10*v10)
xx, yy = map.makegrid(v10.shape[1], v10.shape[0], returnxy=True)[2:4]
map.streamplot(xx, yy, u10, v10, color=speed, cmap=plt.cm.autumn, linewidth=0.5*speed)
map.drawcoastlines(color = '0.15')
plt.show()
注意:
matplotlib 和 basemap 版本要足够高才能使用此函数。如不支持,请升级 matplotlib 和 basemap 版本。
添加文本到地图。
text(x, y, s, fontdict=None, withdash=False, **kwargs)
text 有很多可选参数:
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
map = Basemap(projection='ortho',
lat_0=0, lon_0=0)
map.drawmapboundary(fill_color='aqua')
map.fillcontinents(color='#cc9955',lake_color='aqua')
map.drawcoastlines()
lon = 3.4
lat = 3.4
x, y = map(lon, lat)
plt.text(x, y, 'Lagos',fontsize=12,fontweight='bold',
ha='left',va='bottom',color='k')
lon = 2.1
lat = 41.
x, y = map(lon, lat)
plt.text(x, y, 'Barcelona',fontsize=12,fontweight='bold',
ha='left',va='center',color='k',
bbox=dict(facecolor='b', alpha=0.2))
plt.show()
使用 annotate 可绘制带箭头的文本。
注1:http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.barbs
注2:原文中为 cyl, merc, cyl, gall and mill,多了cyl,可能是作者笔误
注3:地址同 注1
注4:
http://matplotlib.org/examples/pylab_examples/tricontour_vs_griddata.html
注5:http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.contour
注6:http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.hexbin
注7:http://stackoverflow.com/questions/17201172/a-logarithmic-colorbar-in-matplotlib-scatter-plot
注8:http://stackoverflow.com/questions/3765056/combine-picture-and-plot-with-python-matplotlib
http://stackoverflow.com/questions/11487797/python-matplotlib-basemap-overlay-small-image-on-map-plot
注9:http://matplotlib.org/api/markers_api.html
注10:http://matplotlib.org/api/colors_api.html
注11:http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.quiver
注12:http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.streamplot
注13:http://matplotlib.org/1.3.0/api/artist_api.html#matplotlib.patches.FancyArrowPatch