根据经纬度画区域python_用basemap画气象图

basemap 是Python的一个实现地理信息可视化的库,是Matplotlib的一个附加工具包。GrADS在利用“.nc”格式文件的数据绘图时稍显繁琐,basemap就方便很多。

例如现在有一个1948-2010年的逐月月平均气温数据文件“air.mon.mean.nc”,我们试着用basemap画一张1948-2010年1月气温气候场图。

1.读取“.nc”文件中的数据

在读取“.nc”文件的数据时,用到了“netCDF4”库。因此我们先import这个库:

from 

接着读取“air.mon.mean.nc”文件中的内容,并赋值给fh:

fh=Dataset(r'D:fortran5air.mon.mean.nc')

如果想要查看“.nc”文件中有哪些变量:

>>> fh.variables.keys()
dict_keys(['lat', 'lon', 'time', 'air'])

上面结果表明,“.nc”文件中有纬度数据'lat',经度数据'lon',时间数据'time'和变量'air'的数据(也就是气温数据)。

如果想要查看air变量的精度:

>>> fh.variables['air'].shape
(769, 73, 144)

这表示,air有769个时次的数据,纬度有73个格点,经度有144个格点。

最后,我们把这些数据赋值给几个变量:

lons = fh.variables['lon'][:]
lats = fh.variables['lat'][:]
air = fh.variables['air'][:]

2.绘制图像

这一步就要用到basemap库了,同时为了显示图形,还要导入matplotlib中的pyplot库。(为了后续处理数据,还要导入一个numpy库):

from 

画图的第一步,先要初始化一个Basemap类。在初始化这个类的时候,有很多参数可以选择:包括投影方式,经纬度范围等。这里我们采用最简单的:提供地图中心经纬度坐标lat_0和lon_0。

lon0 = lons.mean()
lat0 = lats.mean()
m= Basemap(lat_0=lat0, lon_0=lon0)

这样,我们就得到了这个地图最基本的信息:中心坐标。接下来,我们再为地图添加上海岸线和经纬网格:

m.drawparallels(np.arange(-90., 91., 20.), labels=[1,0,0,0], fontsize=10)
m.drawmeridians(np.arange(-180., 181., 40.), labels=[0,0,0,1], fontsize=10)
m.drawcoastlines()

f16fe3b8f96413fae87056177dd339e8.png

这样一来,我们就有了底图。

由于我们要画的是1948-2010年1月气温气候场图,因此要求1948-2010年1月的平均气温:

ave=np.zeros([73,144])
for i in range(73):
    for j in range(144):
        ave[i,j]=air[0:-1:12,i,j].mean()

接下来,我们要画ave数据的阴影填色图。这要用到Basemap类的一个方法:contourf。在调用这个方法时,最基础的三个参数是坐标xi、yi和数据。这里的数据就对应我们刚刚求得的ave变量。xi、yi是“.nc”文件中的经纬度数据经过如下处理得到的:

lon, lat = np.meshgrid(lons, lats)
xi, yi = m(lon, lat)

这时如果这样调用contourf方法:

m.contourf(xi, yi,ave)

经过显示后,会得到这样的一张图:

04adf79c2f5c2d26a99d89a0188c159c.png

你可能会觉得这个图颜色怪怪的,如果是红蓝色的就更好看了。另外不同的颜色之间过渡不是很平滑(这是划分区域的等值线数值间距太大造成的)。这可以通过给contourf传入额外的参数来改善:

cs = m.contourf(xi, yi,ave,range(-40,41,5),cmap='jet')

这里的第四个参数是用以划分区域的等值线数值。你可以用一个包含了所有想要的数值的列表给出,也可以像这样用range。(这里表示等值线从-40到40,每间隔5℃一条)。另外cmap参数是用来设定地图颜色的。这里的“jet”就是经典的红蓝配色。

如果这时候显示图像,会发现它好看多了:

63b681eb56474a850540c9c5e3295389.png

在此基础上,我们还可以显示颜色图例:

cbar = m.colorbar(cs, location='bottom', pad="10%")

2630fbb1a95afd75b4e7f696a876698f.png

这样一来就更高级了。如果我们还想在这个图上叠加等值线,使得颜色区域边界更明显,可以调用contour方法:

cd=m.contour(xi, yi,ave,range(-40,40,5),colors='k')

这里的参数基本跟contourf的参数是一样的。这里我们把等值线颜色设为黑色(colors='k')。

如果我们想给等值线标上数值的话可以这样:

plt.clabel(cd, inline=True, fmt='%1.0f', fontsize=8, colors='k')

最后一步是显示图像:

plt.show()

运行程序后,可以看到图像:

9f987a22d4d0ca84d85c8cf6f7b758c7.png

3.与GrADS相比,basemap的优势

首先basemap是建立在python基础上的,语法比GrADS更简洁。另外python代码的编辑器有很多,哪一种都比GrADS代码用记事本写强多了(滑稽)。

我们可以对比一下GrADS和basemap的图像:

6ba63427801744e955d72abd9eafdf5e.png
GrADS图像

de3bd5667f169b01728c3aa44a6f4aec.png
basemap图像

同样的一张1948-2010年1月气温气候场图,前者默认颜色是固定的(默认是“rainbow”,不想用这个的话就要自己设置每个区域的颜色,颜色多的时候很麻烦),而后者有很多种颜色可以挑:

cca5fea5d474ff154c6a7bc8b2964dce.png
少女心spring配色

a64d5aad1fc5eb1dc4acc288d2309d73.png
高冷winter配色

另外,最最重要的是,basemap不只是给你一张图,它显示是一个交互界面!

598ca710d97a2f8e0e70da2b1995a641.png

点击左下角的放大镜,可以选择一个矩形区域,对图像局部放大:

84270700f1c89e7c69f2496a3940caa4.png

这一点是不是比GrADS快乐多了?

4.程序完整代码

from