从零开始学习用python处理nc文件并画图,今天先更第一节,怎么从零开始用python中的第三方库basemap画一张图出来。
先说明,我是在虚拟机Ubuntu下的anaconda3和pycharm下载第三方库、画图的。
basemap这个库是用来绘制地图的,语法简单,colorbar也很好看,简直就是地学类学子的福音。但是这个库的安装有点复杂,主要是坑有点多,需要根据自己操作系统的情况多看几篇教程,有时候用Linux系统的也可以从windows下的安装basemap教程中找到灵感,毕竟我等菜鸟用惯了windows 。
windows下安装basemap个人觉得这篇博客挺不错的 ——> 地址在此
linux下安装方法网上也很多,简单记录一下我安装的过程(仅适用于安装了anaconda3的情况!!!):
Step 1. 在连网的前提下,终端输入anaconda-navigator
打开anaconda3
Step 2. 在图形化界面中下载basemap
右侧项目栏 ——> Enviroments ——> 找到uninstalled的,里面就有basemap。当然,我已经装上了所以列表里就没有basemap这个选项了,
选中basemap,然后点击下图中的apply,之后静待安装完毕即可。
Step 3. 安装好后,用简单的代码测试一下
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
#新建地图
map = Basemap() #Basemap类有很多属性,这里全都使用默认参数
#绘制地图
map.drawcoastlines()
# 显示图片
plt.show()
如果成功的话就能得到:
!!!注意事项【引入第三方库时的erro和warning】!!!
①刚装上basemap,输入之后会报错KeyError: PROJ_LIB,这是因为安装basemap的时候,有一个文件夹proj还没有被加入到环境变量中,所以在命令行输入vim ~/.bashrc
,打开后在最后一行加上:export PATH=$PATH:/home/anaconda3/share/proj
。之后在命令行输入source ~/.bashrc
,就可以正常用basemap了
如果有对添加Linux环境变量的各种方法感兴趣的小伙伴可以看这篇博客:Linux添加环境变量方法大全
②在输入from mpl_toolkits.basemap import Basemap
无误之后,map = Basemap()
又双叒叕出问题了
怎么彻底搞定这个错误的方法我还没有找到,但我有一个眼不见为净的方法:
import warnings
warnings.filterwarnings('ignore') #跳开一些报错
就直接给这些无关痛痒的warning跳过就完事了。
numpy库是数据分析库,因为我已经安装了Anaconda,这个库是已经安装好的,这里不再赘述。
windows下安装方法见我之前的博客windows 安装netCDF4
linux下安装教程网上有很多,我是直接在pycharm的setting里下载的netcdf4。
numpy.meshgrid(lon,lat)
将经纬度网格化。contourf(X, Y, Z,cmap=plt.cm.RdBu_r) #X、Y、Z的形状都是m*n*p,用cmap来指定填色图所用的调色板
map = Basemap()
#标识纬线
map.drawparallels(numpy.arange(-70,70,20),labels=[1,0,0,0],fontsize=11)
#标识经线
map.drawmeridians(numpy.arange(-180,180,60),labels=[0,0,0,1],fontsize=11)
需要fontname为Times New Roman的可以直接设置全局字体
import matplotlib.pyplot as plt
plt.rc('font',family='Times New Roman')
注:第一次设置可能会出现错误UserWarning: findfont: Font family [u'Times New Roman'] not found. Falling back to DejaVu Sans (prop.get_family(), self.defaultFamily[fontext]))
,说明没有装上Times New Roman这种字体,需要在命令行(terminal)通过以下代码来安装。
sudo apt install msttcorefonts -qq ##安装
rm ~/.cache/matplotlib -rf ## 重要!!!否则可能装上了但用不了
plt.show()
不能写在plt.savefig('test.png')
之前。import warnings
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import netCDF4 as nc
import numpy as np
#跳开一些报错
warnings.filterwarnings('ignore')
#读取数据
file = "/mnt/hgfs/winshare/ERA_201407.nc"
data =nc.Dataset(file)
# print(data.variables.keys()) #看一下都有哪些变量
#输出经纬度数据
# print(data.variables["latitude"][:])
# print(data.variables["longitude"][:])
#读取经纬度数据、风场数据和时间
lat = data.variables['latitude']
lon = data.variables['longitude']
u10 = data.variables['u10']
time = data.variables['time']
#把只读的数据转为数组,没有这一步会告诉你lon和lat都是read-only
lon=np.array(lon)
lat=np.array(lat)
#只要表层的纬向风速
u10=np.array(u10[0,:,:].squeeze())
#经纬度网格化
for i in range(len(lon)):
lon[i] = lon[i] - 180
Lon,Lat=np.meshgrid(lon,lat)
#输出各矩阵的维度和维数
# print(u10.ndim) #查看数组维度
# print(lon.ndim)
# print(lat.ndim)
# print(u10.shape) #查看数组维数
# print(Lon.shape)
# print(Lat.shape)
#开始画图
map = Basemap()
fig1 = plt.figure()
CS2 = contourf(Lon, Lat, u10,cmap=plt.cm.RdBu_r)
map.colorbar(CS2)
#画纬线
map.drawparallels(np.arange(-70,70,20),labels=[1,0,0,0],fontsize=11)
#画经线
map.drawmeridians(np.arange(-180,180,60),labels=[0,0,0,1],f-ontsize=15)
#叠加地图(海岸线)
map.drawcoastlines(linewidth=0.8) #linewidth设置海岸线的粗细
#设置标题
plt.title('U',size=20)
#保存图片并显示
plt.savefig('test.png')
plt.show()
我的参考教程
ps. 知乎上有一个还不错的关于basemap绘图的解答,里面的源码比较简单,对初学者比较友好 ~~~
链接在此