LiMeteo
Lilidream制作的用于快速绘制ERA5再分析资料的库,基于matplotlib
封装。
优点:
- 简单:语句简单,可面向 Python 初学者。
- 快捷:封装了常用的气象绘图预设,只需要选择绘图要素即可出图。
局限:
- 只支持
netCDF
格式的ERA5
再分析数据。 - 组件封装程度较高,不适于细节调整,不建议用于文章与论文。
- 需要一定
matplotlib
库使用经验运用起来才更加得心应手。
安装
- 下载1.0发行版
- 解压压缩包
- 进入
LiMeteo-1.0
文件夹中 - 运行
python setup.py install
安装即可
例子
绘图流程为:
- 创建
ERA5Plotter
实例并导入数据文件。 - 用
ERA5Plotter.createFigure()
创建画布,相当于plt.figure()
。 - 用
ERA5Plotter.dataSetting()
设置要画的时间和空间范围。 - 绘制水平面图使用
ERA5Plotter.drawMap()
创建地图底图子图;绘制垂直剖面用ERA5Plotter.createSection()
创建剖面图底图。 - 用
ERA5Plotter.drawContour()
等绘图函数画要素。 ERA5Plotter.show()
或ERA5Plotter.save()
,展示或保存。
500hPa高度温度图
500hPa高度+850hPa风+1000hPa温度梯度
多子图与剖面图
下载ERA5的高空多层数据nc格式文件(必须),与地面数据(可选)并画图。
from LiMeteo import ERA5Plotter, ERA5Reader
# 创建实例并加载数据,数据分别为多层气压层与地面数据
p = ERA5Plotter('G:/js/weatherChart/data/20220120-20220131.nc',
'G:/js/weatherChart/data/20220120-20220131_gnd.nc')
# 创建画板,设定大小为(16,7),并调整边距
p.createFigure(figsize=(16, 7), subplotAdj={"left":0.025, "right":0.97, "top":0.95, "bottom":0.08})
# 设置地图范围
mapRange = [80, 140, 10, 60]
# 设置时间与空间范围
p.dataSetting("2022012608", dataRange=mapRange)
# 画第一个子图
p.drawMap((1,2,1), coastalLineColor='#444444', mapRange=mapRange) # 画地图底图
p.drawContour('z', level=500, color='r') # 画500百帕位势高度,红色
p.drawContour('z', level=850, color='b') # 画850百帕位势高度,蓝色
p.drawWindBarb(850, color='g', lowRes=10) # 画850hPa风标,绿色
p.title() # 自动添加标题
# 画第二个子图
p.createSection((1,2,2), 115, dir='y', geoHeight=True) # 画剖面图底图,使用位势高度坐标系
p.drawSection('t',contourf=True) # 画剖面温度填色图
p.drawSectionWindArrow(color='g', lowRes=4, width=0.003) # 画剖面风矢量图
p.title() # 自动添加标题
# 显示画图结果
p.show()
概念
颜色
此类模组中所有的颜色参数均直接传入 matplotlib 中,请参考 matplotlib Specifying Colors 中的颜色值。
lowRes 低分辨率(低采样)
ERA5资料为格点数据,其分辨率为0.25°,在大范围绘制时,不需要那么高的精度,可降低采样率,减少绘制的点数,从而提高绘制的速度。
在此模组中多个绘图函数中都有参数 lowRes = n
,此参数控制绘图中每n个格点取一个值,以减少点数。
- 当
lowRes = 1
时,绘图中每一格点取一个值,即使用原始数据。 - 当
lowRes = 2
时,绘图中每两格点取一个值,即间隔为1:■□■□■□■。 - 当
lowRes = 3
时,绘图中每三格点取一个值,即间隔为2:■□□■□□■□□■。 - 当
lowRes = 4
时,绘图中每四格点取一个值,即间隔为3:■□□□■□□□■□□□■。 对于ERA5 0.25°的分辨率来说,此时分辨率降低到1° - 以此类推……
此功能实为Numpy的切片 array[::lowRes]
。
zorder 图层高度
zorder 参数为 matplotlib 绘图中的图层高度,坐标轴边框的 zorder 为 2,所以填色图 zorder 应该小于等于 2 以不覆盖边框。
默认的 zorder 由高到低排序:
- 4: 等值图
- 3: 风矢量图
- 2: 地图海岸线
- 1: 等值填色图
- 0: 地图陆地海洋填色
参与贡献
- Fork 本仓库
- 新建 Feat_xxx 分支
- 提交代码
- 新建 Pull Request
提出意见与建议
- 提起 Issues
- 通过邮箱或其他方式联系作者, ubuntullmx@hotmail.com
class ERA5Plotter
ERA5Plotter(levelFilePath, landFilePath=None, figsize=(12, 8), printMsg=True, subplotAdj=None)
EAR5数据绘图类,绘图需实例化此类,并传入数据文件路径。
- levelFilePath:
str
必填 高空多层nc数据文件路径 - lanFilePath:
str
地面nc数据文件,时空范围不一定必须与高层相同 - figsize:
list, tuple
画布大小,默认(12, 8) - printMsg:
bool
是否在终端输出过程信息 - subplotAdj:
dict
以字典形式传入plt.subplot_adjust()
函数的参数以设置画布版面
Properties
- ERA5Plotter.reader:
LiMeteo.Reader
类,用于读取数据 - ERA5Plotter.figure:
matplotlib.pyplot.figure
绘图类,当前画布 - ERA5Plotter.figsize:
tuple
图像大小,默认(12, 8) - ERA5Plotter.timeIndex:
int
当前绘图的数据时间索引 - ERA5Plotter.dataRange:
list
当前绘图的数据地理范围,[lonmin, lonmax, latmin, latmax] - ERA5Plotter.lon:
numpy.ndarray
当前绘图的数据经度 - ERA5Plotter.lat:
numpy.ndarray
当前绘图的数据纬度 - ERA5Plotter.ax:
matplotlib.pyplot.axes
当前绘图的数据坐标轴(子图) - ERA5Plotter.gridlines:
cartopy.mpl.gridliner.Gridliner
经纬网格对象 - ERA5Plotter.titleText:
list
绘制数据的标题 - ERA5Plotter.contourValue:
dict
部分数据变量默认等值图的值 - ERA5Plotter.cmap:
dict
部分数据变量默认cmap - ERA5Plotter.colorbarConfig:
dict
填色图色标图例默认属性 - ERA5Plotter.labelFmt:
dict
部分数据变量等值线标签默认格式 - ERA5Plotter.paramName:
dict
部分数据变量的扩展变量名 剖面图相关:
- ERA5Plotter.geiHeight:
bool
当前是否使用位势高度坐标 - ERA5Plotter.geoHeightX:
bool
位势高度x坐标 - ERA5Plotter.geoHeightY:
bool
位势高度y坐标 - ERA5Plotter.sectionLevel:
list, tuple
剖面图气压层范围 - ERA5Plotter.sectionDir:
str
剖面图方向 - ERA5Plotter.sectionLoc:
float
剖面位置 - ERA5Plotter.sectionLim:
list, tuple
剖面范围
- ERA5Plotter.geiHeight:
createFigure()
createFigure(figsize=(12, 8), subplotAdj=None, **kwargs)
封装的 plt.figure()
函数,用于创建画布。
param
- figsize:
list/tuple
图像大小 - subplotAdj:
dict
plt.subplot_adject()
函数的参数 - **kwargs:
plt.figure()
的其他参数。
close()
close()
关闭图像,即 plt.close()
drawMap()
drawMap(subplot=(1,1,1), mapRange=(0, 180, 0, 90), projection="cyl",
landColor=None, oceanColor=None, coastalLineColor=None,
coastLineWidth=0.8, coastalLineZorder=2, colorZorder=0, grid=True,
gridLabels=True, gridColor="#444444", gridStyle=(0, (1, 3)), **gridKwargs)
绘制地图底图的函数,在绘制水平数据前必须先执行该函数创建 subplot
与设置地图坐标系。
param
参数 | 类型 | 必填 | 默认值 | 示例值 | 说明 |
---|---|---|---|---|---|
subplot | list, tuple | 否 | (1,1,1) | (2,2,1) | 子图位置,(行数, 列数, 子图索引),与 matplotlib.pyplot.subplot 的一致,但不能使用三位整数 |
mapRange | list, tuple | 否 | (0, 180, 0, 90) | (90, 120, 20, 40) | 地图显示范围,(经度最小值, 经度最大值, 纬度最小值, 纬度最大值) |
projection | str, crs | 否 | "cyl" | "merc" | 地图投影,可直接传入cartopy.crs 的投影,或传入字符串,可选值为: "cyl" 圆柱投影;"merc" 墨卡托投影; "lambert" 兰伯特投影 |
landColor | "str" | 否 | None | "#888888" | 陆地颜色,不填则不绘制 |
oceanColor | "str" | 否 | None | "#888888" | 海洋颜色,不填则不绘制 |
coastLineColor | "str" | 否 | None | "#888888" | 海岸线颜色,不填则不绘制 |
coastLineWidth | float | 否 | 0.8 | 1 | 海岸线宽度 |
coastLineZorder | float | 否 | 2 | 2 | 海岸线图层高度 |
colorZorder | float | 否 | 0 | 0 | 陆地海洋填色图层高度 |
grid | bool | 否 | True | True | 是否绘制经纬网 |
gridLabels | bool | 否 | True | True | 是否绘制经纬网标签 |
gridColor | str | 否 | "#444444" | "k" | 经纬网颜色 |
gridStyle | list, tuple | 否 | (0, (1, 3)) | (0, (2, 2)) | 经纬网格线样式 |
**gridKwargs | - | 否 | - | - | 直接传入经纬网格函数cartopy.mpl.geoaxes.GeoAxes.gridlines() 中,参考cartopy.mpl.gridliner.Gridliner |
return
ERA5Plotter.ax:matplotlib.pyplot.axes
当前绘图的数据经纬度坐标轴(子图)
show()
显示绘制的图像,就是matplotlib.pyplot.show()
,仅仅为了不用在开头写导入matplotlib
库。
dataSetting()
dataSetting(time, timeFmt="%Y%m%d%H", timeZone=8, dataRange=None)
绘制数据前设置数据时间与空间范围。
- time:
str/int
要绘制的数据时间。若为字符串,则根据timeFmt
的格式解析,若为整数,则视为ERA5数据时间维度的索引。 - timeFmt:
str
时间解析格式,默认为%Y%m%d%H
,即"YYYYMMDDHH",例如"2022060112"(2022年06月01日12时)。请参考datatime.datetime
的时间格式化字符串。 - timeZone:
int
若time
为字符串时该时间的时区,默认为8,即北京时间。 - dataRange:
tuple/list
数据范围,(经度最小值, 经度最大值, 纬度最小值, 纬度最大值),默认为全图范围。
drawContour()
绘制水平的标量分布图,当参数 contourf
为 False
时绘制等值线图,为 True
时绘制等值填色图。
drawContour(self, name=None, level=None, value=None, data=None,
lon=None, lat=None, lowRes=1, contourf=False, cmap=None,
zorder=None, colorbar=True, colorbarLabel=None, extend=None,
CTemp=True, units=None, perks=True, label=True, fontsize=10,
fmt=None, color='k', dagpm=True, linewidth=1, land=False,
addTitle=True, **kwargs):
param
参数 | 类型 | 必填 | 默认值 | 示例值 | 说明 |
---|---|---|---|---|---|
name | str | 否 | None | 't' | 两个nc数据内的非维度变量名称,支持扩展变量名 |
level | int | 否 | None | 500 | 绘制数据的气压层,500hPa则输入500,地面变量此参数无效 |
value | list, ndarray | 否 | None | np.linspace(0, 1, 11) | 设定绘图的等值线值或等值填色的划分值,不填此参数会先从ERA5Plotter.contourValue 中获取对应变量的默认值,若无默认值,则为20 |
data | 2维数组: list, ndarray | 否 | None | - | 自定义传入用于绘图的数据,若传入数组,则name 不生效,同时还要传入此数据对应的经纬度坐标 lon lat |
lon | 1维/2维数组: list, ndarray | 否 | None | - | data 对应的经度坐标,对应plt.contour() 的X |
lat | 1维/2维数组: list, ndarray | 否 | None | - | data 对应的纬度坐标,对应plt.contour() 的Y |
lowRes | int | 否 | 1 | 4 | 每隔多少个格点去一个数据,用于大范围绘制时降低数据分辨率,提升速度 |
contourf | bool | 否 | False | True | 是否绘制为等值填色图 |
cmap | str | 否 | None | "RdBu" | 等值颜色图的映射颜色名,不传入会根据ERA5Plotter.cmap 设置对应变量的cmap,若无预设则为'viridis' |
zorder | float | 否 | None | 4 | 指定图层高度,默认根据类型设置高度 |
colorbar | bool | 否 | True | "RdBu" | 开关填色图色标图例 |
colorbarLabel | str | 否 | None | "Temperature" | 填色图色标图例标签,默认根据所绘变量自动填写 |
extend | str | 否 | None | "both" | 设置填色超过设定值范围时的表现,有效值:"neither", "both", "max", "min",对应 plt.contourf() 的 extend |
CTemp | bool | 否 | True | True | 是否以摄氏度绘制温度 |
units | str | 否 | None | "m/s" | 设置变量单位,默认自动从数据中获取 |
perks | bool | 否 | True | True | 是否以1/(1000s)为涡度散度单位 |
label | bool | 否 | True | True | 等值线是否绘制数值标签 |
fontsize | float | 否 | 10 | 10 | 等值线标签字体大小 |
fmt | str | 否 | None | "%.0f" | 等值线标签格式,默认从 ERA5Plotter.labelFmt 根据变量选择,若无预设则为 "%.1f" |
color | str | 否 | "k" | "r" | 等值线颜色 |
dagpm | bool | 否 | True | True | 位势高度是否使用“什位势米(dagpm)”为单位 |
linewidth | float | 否 | 1 | 1 | 等值线宽度 |
land | bool | 否 | False | False | 当传入自定数据 data 时,此参数设置是否为地面变量 |
addTitle | bool | 否 | True | True | 是否自动将变量名添加到子图标题中(自动设置标题) |
**kwargs | - | 否 | - | - | plt.contour() 或 plt.contourf() 的其他参数 |
return
cartopy.mpl.contour.GeoContourSet
等值图实例(plt.contour()
或 plt.contourf()
的返回值)。
drawWindArrow()
drawWindArrow(level=None, lowRes=8, zorder=3, color='k', width=0.002,
keyX=0.9, keyY=0.9, keyValue=10, addTitle=True, **kwargs)
绘制高空风矢量箭头图。
param
- level:
int
气压层,若为ERA5资料为单层,则此参数无效。 - lowRes:
int
数据采样间隔数。 - zorder:
int
图层高度,默认为55。 - color:
str
箭头颜色,默认为黑色。 - width:
float
箭头宽度,默认为0.002。 - keyX:
float
箭头图例位置x坐标,相对于整个画布。 - keyY:
float
箭头图例位置y坐标,相对于整个画布。 - keyValue:
int
箭头图例值,默认为10m/s。 - addTitle:
bool
是否添加标题 - **kwargs: 绘制箭头 matplotlib.pyplot.quiver() 的其他参数。
return
quiver:matplotlib.pyplot.quiver()
的返回值。
drawWindBarb()
drawWindBarb(level=None, lowRes=16, length=5, zorder=3, color='k', addTitle=True, **kwargs):
绘制高空风风杆风羽。风羽半长度表示2m/s,满长表示4m/s,三角表示20m/s。
param
- level:
int
气压层,若为ERA5资料为单层,则此参数无效。 - lowRes:
int
数据采样间隔数。 - length:
int
风矢量整体大小,默认为6。 - zorder:
int
图层高度,默认为55。 - color:
str
风矢量颜色,默认为黑色。 - addTitle:
bool
是否添加标题 - **kwargs: 绘制矢量 matplotlib.pyplot.barb() 的其他参数。
return
barb:matplotlib.pyplot.barb()
的返回值。
drawGradient()
drawGradient(name, level=None, value=None, lowRes=1, cmap="RdPu", km=True, addTitle=True, **kwargs):
绘制某要素的水平梯度分布图。
param
- name:
str
要素名称,例如位势'z',温度't'。 - level:
int
气压层,若为ERA5资料为单层,则此参数无效。 - lowRes:
int
数据采样间隔数。 - zorder:
int
图层高度,默认为19。 - cmap:
str
图颜色。 - colorbar:
bool
是否绘制颜色标尺,默认为True。 - colorbarLabel:
str
颜色标尺标签。 - ks:
bool
梯度是否以 km 为单位。 - addTitle:
bool
是否添加标题 - **kwargs:
matplotlib.pyplot.contourf()
的其他参数。
return
ERA5Plotter.drawContour()
的返回值
createSection()
createSection(subplot=(1, 1, 1), loc=0, dir='x', lim=None, geoHeight=False, level=None,
geoDagpm=True, geoPres=True, geoPresColor='k', geoPresStyle='--',
geoPresWidth=0.8, geoPresZero=True, fontsize=10, maxMin=True)
创建一个剖面子图,是绘制剖面图的前提。设置 geiHeight
为 True
,可使用位势高度坐标绘图。
param
- subplot:
`list,
tuple` 子图位置,需传入三元数组,与 plt.add_subplot() 相同。 - loc:
float
剖面的位置,若纬向剖面,则为剖面的纬度,经向剖面则为经度。 - dir:
str
剖面方向,纬向为'x',经向为'y',默认为纬向。 - lim:
list,
tuple ,剖面范围,两个元素的数组,分别是[起始经纬度,结束经纬度],若为纬向剖面,则为剖面的经度范围,经向剖面则是纬度范围。默认全部数据范围。 geoHeight:
bool
是否使用位势高度坐标,不使用则为气压坐标。- geoDagpm:
bool
位势高度坐标使用什位势米(dagpm)为单位。 geoPres:
bool
在位势高度坐标上绘制等压面。- geoPresColor:
str
等压面等值线颜色。 - geoPresStyle:
str
等压面等值线样式,默认虚线。 - geoPresWidth:
float
等压面等值线线宽,默认0.8。 - fontsize:
float
等压面等值线标签字体大小
- geoPresColor:
- geoPresZero:
bool
是否绘制0位势高度横线。 - maxMin:
bool
使用位势高度坐标时,是否使气压层做大最小值顶格到画框边缘(充满画布)
- geoDagpm:
return
ERA5Plotter.ax 当前子图
drawSection()
def drawSection(name, value=None, lowRes=1, cmap=None, contourf=False,
color='k', linewidth=1, label=True, colorbar=True, fontsize=10,
fmt="%.1f", CTemp=True, perks=True, dagpm=True, extend=None,
zorder=None, colorbarLabel=None, units=None, addTitle=True, **kwargs):
绘制某元素的经向/纬向垂直分布等值图。
param
大部分参数与 drawContour()
相同。数据范围使用 createSection()
设置。
- name:
str
必填 变量名,暂不支持输入自定数据。
return
plt.contour()
或 plt.contourf()
的返回值。
drawSectionWindArrow()
drawSectionWindArrow(amp=100, lowRes=8, zorder=3, color='k', width=0.002, keyX=0.9,
keyY=0.9, keyValue=10, addTitle=True, **kwargs):
绘制风箭头图。若绘制多张风箭头图,请使用**kwargs传入参数使风箭头缩放倍数固定。
------ 注意 ------
※※垂直速度单位为 Pa/s,此处绘图并未转换为 m/s!
※※因此绘图结果并不能完全表示真实情况!
param
大部分参数与 drawWindArrow() 相同。
- amp:
float
垂直速度放大倍数。 - **kwargs: 绘制箭头 matplotlib.pyplot.quiver() 的其他参数。
返回
matplotlib.pyplot.quiver() 的返回值。
drawSectionWindBarb()
drawSectionWindBarb(self, lowRes=16, length=5, zorder=3, color='k', addTitle=True, **kwargs)
绘制垂直剖面上的水平风矢量图。风羽一半长度表示2m/s,满长表示4m/s,三角表示20m/s。
因为风矢量图标较大,所以大范围绘图时,lowRes需调大,不然太密集。
------ 注意 ------
※※垂直速度单位为 Pa/s,此处绘图并未转换为 m/s!
※※因此绘图结果并不能完全表示真实情况!
param
大部分参数与 drawWindBard() 相同。
- **kwargs: 绘制箭头 matplotlib.pyplot.quiver() 的其他参数。
return
barb:matplotlib.pyplot.barb() 的返回值。
getData()
getData(name, level=None, timeIndex=None, lowRes=1)
获取单层数据。数据的时间空间范围可通过 dataSetting()
设置。
param
- name:
str
必填 变量名称,支持paramName
的扩展变量名。 - level:
int
气压高度层 - timeIndex:
list, tuple
两个值的数组,要获取的数据的时间索引范围,如(3, 8)
,时间索引可使用reader.converTimeBack(strTime, timeFmt="%Y%m%d%h", timeZone=8, land=False)
函数将格式化时间转换回时间索引。 若此参数不传入,则默认获取由dataSetting()
设置的单个时次数据。 - lowRes:
int
设置数据的间隔采样。
return
2维/3维 ndarray(时间轴长度为一时自动转成2维数据)
title()
title(text=None, time=True, fontsize=10, timeZone=8)
为子图设置标题,当以上绘图函数的参数 addTitle
为 True
时,会向 titleText
添加该图的标题,绘图函数执行完后,执行此函数将标题显示。
param
- text:
str
手动设置标题内容,若为空,则为绘图内容自动添加的标题。 - time:
bool
输出时间 - fontsiez:
float
标题字体大小 - time:
int
标题时间的时区,若为8
时自动添加CST
后缀。
return
None
suptitle()
suptitle(text, fontsize=14, y=0.95)
设置总标题。
param
- text:
str
标题内容 - fontsize:
float
标题字体大小 - y:
float
相对画布的y轴位置
return
None
save()
save(path, **kwargs)
plt.savefig()
的简单封装。
param
- path:
str
保存的路径。 - **kwargs
plt.savefig()
的其他参数。
return
None
presetFigure()
presetFigure(mapRange, time, timeFmt="%Y%m%d%H",show=True, savePath=None)
6张子图的预设函数。运行会绘图。
param
- mapRange:
list
四元素数组的地图范围 - time:
str
格式化的时间 - timeFmt:
str
格式化时间的格式 - show:
bool
是否显示画图结果 - savePath:
str
图画保存路径,若不填则不保存
return
None