你就快到了,但基本地图可能是喜怒无常的,你必须管理绘图/地图细节的z顺序。另外,在使用basemap绘制之前,必须将lon/lat坐标转换为映射投影坐标。
这里有一个完整的解决方案,它给出了以下输出。为了使整件事更清晰,我改变了一些颜色和线宽。我还将散点的大小按标准化的“平均”值(data['Z'])进行了缩放——如果您希望使用恒定大小(它看起来像最大的标记),可以简单地将其移除并替换为50。
如果可能的话,还请具体说明降雨量的单位和产生该方法的测量持续时间:
import numpy as np
import pandas as pd
from matplotlib.mlab import griddata
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize
%matplotlib inline
# set up plot
plt.clf()
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, axisbg='w', frame_on=False)
# grab data
data = pd.read_csv('../../data/meansr.txt', delim_whitespace=True)
norm = Normalize()
# define map extent
lllon = 21
lllat = -18
urlon = 34
urlat = -8
# Set up Basemap instance
m = Basemap(
projection = 'merc',
llcrnrlon = lllon, llcrnrlat = lllat, urcrnrlon = urlon, urcrnrlat = urlat,
resolution='h')
# transform lon / lat coordinates to map projection
data['projected_lon'], data['projected_lat'] = m(*(data.Lon.values, data.Lat.values))
# grid data
numcols, numrows = 1000, 1000
xi = np.linspace(data['projected_lon'].min(), data['projected_lon'].max(), numcols)
yi = np.linspace(data['projected_lat'].min(), data['projected_lat'].max(), numrows)
xi, yi = np.meshgrid(xi, yi)
# interpolate
x, y, z = data['projected_lon'].values, data['projected_lat'].values, data.Z.values
zi = griddata(x, y, z, xi, yi)
# draw map details
m.drawmapboundary(fill_color = 'white')
m.fillcontinents(color='#C0C0C0', lake_color='#7093DB')
m.drawcountries(
linewidth=.75, linestyle='solid', color='#000073',
antialiased=True,
ax=ax, zorder=3)
m.drawparallels(
np.arange(lllat, urlat, 2.),
color = 'black', linewidth = 0.5,
labels=[True, False, False, False])
m.drawmeridians(
np.arange(lllon, urlon, 2.),
color = '0.25', linewidth = 0.5,
labels=[False, False, False, True])
# contour plot
con = m.contourf(xi, yi, zi, zorder=4, alpha=0.6, cmap='RdPu')
# scatter plot
m.scatter(
data['projected_lon'],
data['projected_lat'],
color='#545454',
edgecolor='#ffffff',
alpha=.75,
s=50 * norm(data['Z']),
cmap='RdPu',
ax=ax,
vmin=zi.min(), vmax=zi.max(), zorder=4)
# add colour bar and title
# add colour bar, title, and scale
cbar = plt.colorbar(conf, orientation='horizontal', fraction=.057, pad=0.05)
cbar.set_label("Mean Rainfall - mm")
m.drawmapscale(
24., -9., 28., -13,
100,
units='km', fontsize=10,
yoffset=None,
barstyle='fancy', labelstyle='simple',
fillcolor1='w', fillcolor2='#000000',
fontcolor='#000000',
zorder=5)
plt.title("Mean Rainfall")
plt.savefig("rainfall.png", format="png", dpi=300, transparent=True)
plt.show()
使用matplotlib的griddata方法很方便,但也可能很慢。作为替代方案,您可以使用scipy的griddata方法,这些方法既快又灵活:from scipy.interpolate import griddata as gd
zi = gd(
(data[['projected_lon', 'projected_lat']]),
data.Z.values,
(xi, yi),
method='linear')
如果使用scipy的griddata方法,还必须确定哪些方法(nearest,linear,cubic)给出了最佳的结果图。
我要补充的是,上面演示和讨论的插值方法是最简单的,不一定适用于降雨数据的插值。This article很好地概述了水文和水文模型中使用的有效方法和注意事项。这些(可能使用Scipy)的实现作为一个练习&c