写下来主要是作为自己的笔记
全球海温数据下载后是 .nc
格式的文件,它就是 Netcdf 文件。 NetCDF 全称为 Network Common Data Format,中文译法为“网络通用数据格式”。
Netcdf 文件开始的目的是用于存储气象科学中的数据,现在已经成为许多数据采集软件的生成文件的格式。
从数学上来说,Netcdf 存储的数据就是一个多自变量的单值函数。用公式来说就是f(x,y,z,…)=value 。
函数的自变量 x,y,z 等在 Netcdf 中叫做维(dimension) 或坐标轴(axix)。
函数值 value 在 Netcdf 中叫做变量(Variables)。
自变量和函数值在物理学上的一些性质,在 Netcdf 中就叫属性(Attributes)。
一个 Netcdf 文件的结构包括以下对象:
netCDF4
,安装命令为:pip install netcdf4
。读取全球海温数据并查看其所有属性:
from netCDF4 import Dataset
nc_obj = Dataset('ERsst.mnmean.nc')
for i in nc_obj.variables:
print(i)
# 查看 sst 变量的信息
print(nc_obj.variables['sst'])
输出如下,为文件的各类信息:
lat
lon
time_bnds
time
sst
float32 sst(time, lat, lon)
long_name: Monthly Means of Sea Surface Temperature
units: degC
var_desc: Sea Surface Temperature
level_desc: Surface
statistic: Mean
missing_value: -9.96921e+36
dataset: NOAA Extended Reconstructed SST V5
parent_stat: Individual Values
actual_range: [-1.8 42.32636]
valid_range: [-1.8 45. ]
unlimited dimensions: time
current shape = (1973, 89, 180)
filling on, default _FillValue of 9.969209968386869e+36 used
可以看出 sst 变量,在访问数据时需要传入三个参数,时间、纬度、经度。
查看 1958 年的全球海温数据:
from netCDF4 import Dataset
nc_obj = Dataset('ERsst.mnmean.nc')
temperature = nc_obj.variables['sst'][1958, :, :]
print(temperature)
print(temperature.shape)
输出结果:
[[-1.7999999523162842 -1.7999999523162842 -1.7999999523162842 ...
-1.7999999523162842 -1.7999999523162842 -1.7999999523162842]
[-1.7999999523162842 -1.7999999523162842 -1.7999999523162842 ...
-1.7999999523162842 -1.7999999523162842 -1.7999999523162842]
[-1.7999999523162842 -1.7999999523162842 -1.7999999523162842 ...
-1.7999999523162842 -1.7999999523162842 -1.7999999523162842]
...
[-- -- -- ... -- -- --]
[-- -- -- ... -- -- --]
[-- -- -- ... -- -- --]]
(89, 180)
可以看出,该数据只记载了海洋的温度,而大陆的温度由 --
表示。
绘制热力图
绘制全球海温时,首先要在图像上绘制出,全球海温各地数值,所以需先绘制全球海温的热力图。
from netCDF4 import Dataset
import matplotlib.pyplot as plt
import numpy as np
nc_obj = Dataset('ERsst.mnmean.nc')
temperature = nc_obj.variables['sst'][1958, :, :]
lat, lon = temperature.shape
plt.figure(figsize=(10, 5))
plt.imshow(temperature, cmap='Spectral_r')
x = plt.colorbar()
x.set_label('Temperature')
plt.show()
可视化效果如下:
图一 全球海温数据绘制热力图
参数分析:
plt.imshow()
其实就是将数组的值以图片的形式展示出来,数组的值对应着不同的颜色深浅,而数值的横纵坐标就是数组的索引,比如一个 1000X1000
的数组,图片里的点也就有 1000X1000
个,比如第一个行第一个点的坐标就是 (0,0)
,它的值会通过 colorbar
(也就是 cmap
参数)反映出来,也就可以说 plt.imshow()
函数的功能就是把数值展示成热图。
而 cmap
参数是指绘制图像的颜色参考系,还有众多的颜色模板可以进行设置,如下图:
图二 颜色模板
本次选用的就是 Spectral
,相对而已比较符合温度的代表色彩,而 Spectral_r
后面的 _r
则表示颜色取反。
plt.colorbar()
就是创建一个子图,在绘制图像的旁边,用于显示数值与颜色的对应关系。
绘制等高线
绘制全球海温,可不只有热力图的绘制,还可以绘制等高线,来很直观的展示具有相同温度的海域,有较重要的研究意义。
from netCDF4 import Dataset
import matplotlib.pyplot as plt
import numpy as np
nc_obj = Dataset('ERsst.mnmean.nc')
temperature = nc_obj.variables['sst'][1958, :, :]
lat, lon = temperature.shape
X, Y = np.meshgrid(range(lon), range(lat))
plt.figure(figsize=(10, 5))
# 画出 8 个级别的线,并将颜色设置为黑色
contour = plt.contour(X, Y, temperature, 8, colors='k')
# 等高线上标明z(即高度)的值,字体大小是7,颜色分别是黑色
plt.clabel(contour, fontsize=7, colors='k')
plt.show()
可视化效果如下:
图三 全球海温数据绘制等高线图
函数分析: 生成坐标矩阵
语法:X,Y = numpy.meshgrid(x, y)
。
参数 | 说明 |
---|---|
x,y | 网格点的横纵坐标列向量(非矩阵) |
X,Y | 坐标矩阵 |
X, Y = np.meshgrid(range(lon), range(lat))
是用于生成网格点坐标矩阵的,具体将生成数组效果如下
lon = 180
lat = 89
X, Y = np.meshgrid(range(lon), range(lat))
print(X.shape, Y.shape)
print(X)
print(Y)
(89, 180) (89, 180)
[[ 0 1 2 ... 177 178 179]
[ 0 1 2 ... 177 178 179]
[ 0 1 2 ... 177 178 179]
...
[ 0 1 2 ... 177 178 179]
[ 0 1 2 ... 177 178 179]
[ 0 1 2 ... 177 178 179]]
[[ 0 0 0 ... 0 0 0]
[ 1 1 1 ... 1 1 1]
[ 2 2 2 ... 2 2 2]
...
[86 86 86 ... 86 86 86]
[87 87 87 ... 87 87 87]
[88 88 88 ... 88 88 88]]
输出中的 X
是将 [0, lon)
纵向复制 lat
份, Y
是将 [0, lat)
横向复制 lon
份,所以 X
,Y
的矩阵形状都是一样的为 (89, 180)
。将 X,Y 数据矩阵对应组合就会形成网格坐标,绘制等高线时需要网格进行线条的绘制。
绘制等高线语法:plt.contour([X, Y,] Z, [levels], **kwargs)
。
参数说明:
参数 | 作用 |
---|---|
X,Y | array-like,可选值 Z 的坐标。X 和 Y 必须都是 2-D ,且形状与 Z 相同,或者它们必须都是 1-d ,这样 len(X)== M 是 Z 中的列数,len(Y)== N 是 Z 中的行数 。 |
Z | array-like(N,M) 绘制等高线的高度值。 |
levels | int 或类似数组,可选确定等高线/区域的数量和位置。如果int Ñ ,使用 Ñ 数据间隔; 即绘制 n + 1 个等高线。水平高度自动选择。如果是数组,则在指定的级别绘制等高线。值必须按递增顺序排列。 |
根据提示,在右侧编辑器补充代码,结合热力图以及等高线的绘制方法,绘制全球海温。
平台会对你编写的代码进行测试。 效果图如下:
图四 绘制完成最终效果图
import matplotlib as mpl
# linux终端下没有GUI,进行设置
mpl.use('Agg')
from netCDF4 import Dataset
import matplotlib.pyplot as plt
import numpy as np
nc_obj = Dataset('step5/ERsst.mnmean.nc')
########## Begin ##########
# 获取 1970 年的全球海温数据
temperature = nc_obj
temperature = temperature.variables['sst'][1970,:,:]
########## End ##########
lat, lon = temperature.shape
# 生成网格点坐标矩阵
X, Y = np.meshgrid(range(lon), range(lat))
# 添加画布,画布尺寸宽为 10,长为 5
plt.figure(figsize=(10, 5))
########## Begin ##########
# 传入海温数据绘制热力图,cmap 参数选择 coolwarm
plt.imshow(temperature, cmap='coolwarm')
########## End ##########
# 绘制色彩子图
x = plt.colorbar()
########## Begin ##########
# 设置子图标签,为 Temperature
x.set_label('Temperature')
########## End ##########
########## Begin ##########
# 画出 7 条线,并将颜色设置为红色
contour = plt.contour(X, Y, temperature,7, colors='r')
########## End ##########
# 等高线上标明z(即高度)的值,字体大小是7,颜色分别是红色
plt.clabel(contour, fontsize=7, colors='r')
# 保存图像
plt.savefig('step5/image1/test.png')