啊我们这次需要用的库有:
如果发现cartopy安装不了,可以先在网站下载依赖库。
分别是:
我们下载好对应Python版本和OS类型的.whl
文件后,在anaconda prompt
中输入以下命令:
pip install path\your_file.whl
即可。
关于海洋遥感数据,我们可以在https://podaac.jpl.nasa.gov/上下载数据,当然,NASA的这个网站可能需要科学上网。
我们下载下来的文件是.nc
文件,这个类型的文件可以用xarray
或者netCDF4
这两个库进行读取哦。下面我们展示xarray
的读取方式。
# 导入库
import xarray as xr
值得一提的是,xarray
有可能跟pytorch
或者tensoflow
产生冲突,尤其是torchtext
库。这种情况下,可能需要对现有的依赖库进行更新。
# 读取数据
data = xr.open_dataset(d)
此时呢,数据就被我们读取进来啦。我们这次需要用到的值为SST(sea surface temperature),因此,我们需要获取到这个维度的数据。
sst = data.variables["sea_surface_temperature"][:] # 通过variables属性 选择对应维度的数据
# 获取经纬度数据
lon = data.variables['lon'][:]
lat = data.variables['lat'][:]
这些数据符不符合规范,是一个值得注意的问题。我们发现,该文件的SST数据缺失了不少值,需要做一个清洗。
# 获取到DataFrame方便处理
sst = np.array(sst)
d = pd.DataFrame(sst[0])
print(d.describe())
# 用平均值填充
d.fillna(d.mean(), inplace=True)
好啦我们现在要用到cartopy
进行绘图啦~
# 之前拿到的数据是xarray类型的,我们需要转换到ndarry类型
lon,lat=np.array(lon),np.array(lat)
sst=d.values
设置我们地图的投影
ax = plt.axes(projection=ccrs.PlateCarree()) # 设置投影方式
extend=[-30,-16, -60, -46] # 设置显示范围
ax.set_extent(extend) # 设置经纬度范围
ax.stock_img()#添加地球背景
ax.add_feature(cfe.OCEAN) # 添加要素
ax.add_feature(cfe.LAND,edgecolor='black')
ax.add_feature(cfe.LAKES,edgecolor='black')
ax.add_feature(cfe.RIVERS)
rivers_10m = cfe.NaturalEarthFeature('physical', 'rivers_lake_centerlines', '10m')
ax.add_feature(rivers_10m,facecolor="None",edgecolor='b')
ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=0.2, color='k', alpha=0.5, linestyle='--') # 添加经纬网
ax.coastlines() # 设置海岸线
ax.set_title("我也不知是啥数据")
levels = np.arange(sst.min(), sst.max()+ 1, 1) # 设置颜色分辨度
cp=ax.contourf(lon,lat,sst,cmap='Spectral_r',levels=levels) # 绘制二维格网
plt.colorbar(cp)# 设置色带
plt.show()
这里我们就需要使用到imageio
模块了。
这里简单说一下如何通过imageio
制作gif
动图。
首先,我们需要通过imageio.imread()
API读取图片数据,将其存放在容器列表中。再通过imageio.mimsave()
进行制作。
# 定义一个创建gif的方法
def create_gif(filelist,name,dur=1.0)->None:
IMG=[]
for i in filelist:
IMG.append(imageio.imread(i))
return imageio.mimsave(name,IMG,"GIF",duration=dur)
接着获取plt
的图像资源
plt.savefig((val:=path+"%s.png"%time),dpi=200)
lis.append(val)
# 释放资源
plt.close()
最终结果如下图啦,数据是随便拉的,所以对不太上
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import cartopy.feature as cfe
import xarray as xr
import imageio
import numpy as np
import pandas as pd
import os
# 创建gif图像
def create_gif(filelist,name,dur=1.0)->None:
IMG=[]
for i in filelist:
IMG.append(imageio.imread(i))
return imageio.mimsave(name,IMG,"GIF",duration=dur)
def working(d,path,time,lis)->None:
# 数据清洗
'''
:param data: 数据
:param path: 保存路径
:param time: 名字吧
:param lis: GIF文件夹
:return:
'''
data = xr.open_dataset(d)
sst = data.variables["sea_surface_temperature"][:]
lon = data.variables['lon'][:]
lat = data.variables['lat'][:]
sst = np.array(sst)
d = pd.DataFrame(sst[0])
# print(d.describe())
d.fillna(d.mean(), inplace=True)
lon,lat=np.array(lon),np.array(lat)
sst=d.values
ax = plt.axes(projection=ccrs.PlateCarree()) # 设置投影方式
extend=[-30,-16, -60, -46]
ax.set_extent(extend) # 设置经纬度范围
ax.stock_img()#添加地球背景
ax.add_feature(cfe.OCEAN)
ax.add_feature(cfe.LAND,edgecolor='black')
ax.add_feature(cfe.LAKES,edgecolor='black')
ax.add_feature(cfe.RIVERS)
rivers_10m = cfe.NaturalEarthFeature('physical', 'rivers_lake_centerlines', '10m')
ax.add_feature(rivers_10m,facecolor="None",edgecolor='b')
ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=0.2, color='k', alpha=0.5, linestyle='--')
ax.coastlines()
ax.set_title("我也不知是啥数据")
levels = np.arange(sst.min(), sst.max()+ 1, 1) # 设置绘画精度
cp=ax.contourf(lon,lat,sst,cmap='Spectral_r',levels=levels)
plt.colorbar(cp)
# ax.set_xticks(np.arange(extend[0],extend[1],5))
# ax.set_yticks(np.arange(extend[2],extend[3],5))
plt.savefig((val:=path+"%s.png"%time),dpi=200)
lis.append(val)
# 释放资源喽
plt.close()
if __name__ == '__main__':
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# plt.rcParams['axes.unicode_minus'] = False # Solve the minus sign problems # 现在好像不设置也没有问题了?
path=r"C:\"
filelist=os.listdir(path)
Time=[]
filedata=[]
for i,j in enumerate(filelist):
if j.endswith(".nc"):
Time.append(i)
filedata.append(j)
IMG=[]
savePath=path+"SavePath\\"
if not os.path.exists(savePath):
os.makedirs(savePath)
for i,j in enumerate(filedata):
working(path+j,savePath,Time[i],IMG)
create_gif(IMG,savePath+"New.gif",1.0)