python爬取天气数据并制图(python爬虫爬取天气预报)
Python气象数据处理与绘图(1):数据读取
python很多库支持了对nc格式文件的读取,比如NetCDF4,PyNio(PyNio和PyNgl可以看做是NCL的Python版本)以及Xarray等等。
我最初使用PyNio,但是由于NCL到Python的移植并不完全,导致目前远不如直接使用NCL方便,而在接触Xarray库后,发现其功能强大远超NCL(也可能是我NCL太菜的原因)。
安装同其它库一致:
我这里以一套中国逐日最高温度格点资料(CN05.1)为例,其水平精度为0.5°X0.5°。
可以看到,文件的坐标有时间, 经度,纬度,变量有日最高温
我们将最高温数据取出
这与Linux系统中的ncl_filedump指令看到的信息是类似的
Xarray在读取坐标信息时,自动将时间坐标读取为了datetime64 格式,这对我们挑选目的时间十分方便。Xarray通常与pandas配合使用。
比如我们想选取1979.06.01-1979.06.20时期数据,我们只需
再比如我们想选取夏季数据时,只需
更多的时间操作同python的datetime函数类似。
当我们想选取特定经纬度范围(高度)的数据时,.loc[]函数同样可以解决。
在这里,我选取了40°N-55°N,115°E-135°E范围的数据
甚至,我们还可以套娃,同时叠加时间和范围的选取
这足够满足常用到的数据索引要求。
对于这类简单排列的.txt文件,可以通过np.load读取,用pandas的.read_csv更为方便
读取txt的同时,对每列赋予了一个列名,通过data.a可以直接按列名调用相应数据。
对于较复杂的.txt文件,仍可通过该函数读取
skiprows=5跳过了前5行的文件头,sep='\s+'定义了数据间隔为空格,这里用的是正则表达。
pd.read_csv函数有很多的参数,可以处理各种复杂情况下的文本文件读取。
grib文件可通过pygrib库读取
import pygrib
f = pygrib.open('xxx.grb')
python气象绘图windrose
#导入包
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from matplotlib.ticker import FuncFormatter
import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']? #设置简黑字体
mpl.rcParams['axes.unicode_minus'] = False? #设置负号正常显示
#----获取数据DataFrames,index*columns。index表示不同值范围,columns表示十六个风向
data = pd.DataFrame(wind_d_max_num_per,
? ? ? ? ? ? ? ? ? ? index=['15', '15~25', '25~35', '35~45',"≥45"],
? ? ? ? ? ? ? ? ? ? columns='N NNE NE ENE E ESE SE SSE S SSW SW WSW W WNW NW NNW'.split())
N = 16 # 风速分布为16个方向
theta = np.linspace(0, 2*np.pi, N, endpoint=False) # 获取16个方向的角度值
width = np.pi / 4 * 0.4? # 绘制扇型的宽度,可以自行调整0.5时是360,充满,有间隔的话小于0.5即可
labels = list(data.columns) # 自定义坐标标签为 N , NSN, ……# 开始绘图
plt.figure(figsize=(6,6),dpi=600)
ax = plt.subplot(111, projection='polar')
#----自定义颜色
mycolor =['cornflowerblue','orange','mediumseagreen','lightcoral','cyan']
#----循环画风玫瑰图
i=0
for idx in data.index:
? ? print(idx)
? ? # 每一行绘制一个扇形
? ? radii = data.loc[idx] # 每一行数据
? ? if i == 0:
? ? ? ? ax.bar(theta, radii, width=width, bottom=0.0, label=idx, tick_label=labels,
? ? ? ? ? color=mycolor[i])
? ? else:
? ? ? ? ax.bar(theta, radii, width=width, bottom=np.sum(data.loc[data.index[0:i]]), label=idx, tick_label=labels,
? ? ? ? ? color=mycolor[i])
? ? i=i+1
#此种画法,注意bottom设置,第一个bottom为0,后续bottom需要在前一个基础上增加。
ax.set_xticks(theta)
ax.set_xticklabels(labels,fontdict={'weight':'bold','size':15,'color':'k'})
ax.set_theta_zero_location('N') #设置零度方向北
ax.set_theta_direction(-1)? ? # 逆时针方向绘图
#----设置y坐标轴以百分数显示
plt.gca().yaxis.set_major_formatter(FuncFormatter(lambda s, position: '{:.0f}%'.format(100*s)))
plt.legend(loc=4, bbox_to_anchor=(0.05, -0.25),fontsize=12) # 将label显示出来, 并调整位置
#----保存图片
plt.savefig("./windrose1.svg")
Python气象数据处理与绘图(18):泰勒图
泰勒图绘制的核心思想是设计一个只有第一象限的极坐标,并将方差,相关系数进行捆绑,通过转化为极坐标系坐标进行绘制。为了实现泰勒图的绘制,我设计了两个函数:
set_tayloraxes(fig, location=111) 和plot_taylor(axes, refsample, sample, args, *kwargs)
set_tayloraxes()函数用于建立一个泰勒图的坐标系,这个自定义函数一般情况下不建议修改,每一个参数都是经过多次调试得到的,很可能牵一发动全身。因此,将绘图部分的独立成为了plot_taylor函数(),这部分函数较为简单,目的就是将需要绘图的数据,转换为极坐标系坐标,通过plot函数将散点打在泰勒图上,这个函数模块较为简单,可以根据自己的输入数据情况进行调整。
下面介绍下函数的具体用法:
输入:
fig: 需要绘图的figure
rect:图的位置,如111为1行1列第一个,122为1行2列第2个
输出:
polar_ax:泰勒坐标系
输入:
axes : setup_axes返回的泰勒坐标系
refsample :参照样本
sample :评估样本
args, *kwargs :plt.plot()函数的相关参数,设置点的颜色,形状等等。
下面给出示例:
Python气象数据处理与绘图(12):轨迹(台风路径,寒潮路径,水汽轨迹)绘制
寒潮是笔者主要的研究方向,寒潮路径作为寒潮重要的特征,是寒潮预报的重点之一,同样的道理也适用在台风研究以及降水的水汽来源研究中。关于路径的计算以及获取方法(比如轨迹倒推,模型追踪等等方法,台风有自己现成的数据集,比如ibtracs数据集等等)并不在本文的介绍范围之内,本文主要介绍在获取了相应的路径坐标后,如何在图中美观的展现。
上图展现了近40年东北亚区域的冬季冷空气活动路径,绘制这类图需要的数据只需为每条路径的N个三维坐标点,第一第二维分别为longitude和latitudee,第三维则比较随意,根据需要选择,比如说需要体现高度,那就用高度坐标,需要体现冷空气强度,那就用温度数据,水汽可以用相对湿度,台风也可以用速度等等。
通常此类数据是由.txt(.csv)等格式存储的,读取和处理方法可参考我的“Python气象数据处理与绘图(1):数据读取”,本文主要介绍绘图部分。
当然根据需要,也可以直接绘制两维的轨迹,即取消掉颜色数组,用最简单的plot语句,循环绘制即可。
有一个陷阱需要大家注意的是,当轨迹跨越了东西半球时,即穿越了0°或者360°经线时,它的连接方式是反向绕一圈,比如下图所示,你想要蓝色的轨迹,然而很有可能得到绿色的,这是因为你的网格数组的边界是断点,系统不会自动识别最短路径,只会在数组中直接想连,因为这不是循环数组。
我目前的解决办法是这样的:如果你的数据是0°-360°格式,那么变为-180°-180°的格式,反之相互转换。但是如果你的数据两种都出现了断点,也就是绕了地球一圈多,那无论怎样都么得办法了,我目前的思路是将数据转换成极坐标数据格式,理论上是可行的,CARTOPY的绘图也是支持极坐标数据的,具体实施还需要再试试。