import matplotlib.pyplot as plt
import numpy as np
import xarray as xr
ds1 = xr.open_dataset("..\air.2020.nc", drop_variables = ["time_bnds"]).sel(level = 850).rename({"air": "Tair"})
ds = ds1.sortby("lat", ascending= True)
r_equator = 6378.137e3
r_polor = 6356.752e3
dx = np.deg2rad(2.5) * r_equator * np.cos(ds.lat * np.pi / 180)
dy = np.deg2rad(2.5) * r_polor
ds["dTdx"] = ds.Tair.differentiate("lon") / dx
ds["dTdy"] = ds.Tair.differentiate("lat") / dy
ds.dTdx.attrs = {"long_name": "$∂T/∂x$", "units": "°C/m"}
ds.dTdy.attrs = {"long_name": "$∂T/∂y$", "units": "°C/m"}
一维数据绘图(Ⅰ)
基础线图绘制
xarray 通过对plt.plot()
的包装实现对线图的绘制。如前面所述,axes
可以用变量进行标记,从而可以传递给底层matlibplot
调用。
首先提取北纬 60°,西经 110° 处时间变化数据
代码语言:javascript复制data1d = ds.Tair.sel(lat=60, lon=250)
data1d
data1d
尝试直接使用.plot()
方法绘图
data1d.plot()
data1d.plot()
似乎图在水平方向上稍显拥挤,有办法使得画板水平方向更加宽松吗?当然有。参数figsize
可设置画板尺寸。既然可以调整画板尺寸,那么画板纵横比的调整便不难实现啦。下面给出一个实例:
data1d.plot(figsize = (10,4), marker="o")
.plot()
方法中的参数figsize
本质传递给了底层plt.figure
. 若以脚本层绘图方法有如下理解:
plt.figure(figsize=(10,4))
data1d.plot(marker="o")
艺术家方法有类似的结果
代码语言:javascript复制fig = plt.figure(figsize=(10,4))
ax = plt.axes()
# 或一步法创建 fig, ax = plt.subplots(figsize=(10,4))
data1d.plot(ax = ax, marker="o")
更底层可通过Numpy 数组理解线图的绘制方法
代码语言:javascript复制fig, ax = plt.subplots(figsize=(10,4))
x = data1d.time.data
y = data1d.data
ax.plot(x, y, marker="o")
xarray 提取坐标名称和与此紧密相关的元数据attrs.long_name
, attrs.standard_name
, DataArray.name
, attrs.units
(若存在该项值)标记坐标轴的标签。名称long_name
、standard_name
、units
符合CF 规范[1]。xarray 数据的属性可用.attrs
方法获取。
data1d.attrs
data1d.attrs
类似于MATLAB 线图绘制[2],可用类似的参数指定绘制线型、标记和颜色。
代码语言:javascript复制data1d.plot.line("b-^", figsize = (10,4))
线图绘制参数字符串b-^
中的参数由三个对线图绘制的属性组成:线型(Line Styles)、标记(Markers)、颜色(Colors). 这三个参数的顺序可以交换,也可以不必全部指定。
字符串参数顺序最好为
'[标记][线型][颜色]'
,其他顺序形式可能会导致错误。若未全指定上述所有属性,则采用相应属性的默认值。
当然也可使用 python 参数marker
, linestyle 或ls
, color 或c
分别指定上述属性。
data1d.plot.line(marker = "^", ls = "-", c = "b", figsize = (10,4))
参数marker
参数marker
表可参见matplotlib.markers[3]
matplotlib.markers
Matlibplot 官网[4]给出了不同标记的示例,可参见如下
代码语言:javascript复制import numpy as np
import matplotlib.pyplot as plt
# 随机数种子
np.random.seed(19680801)
x = np.random.rand(10)
y = np.random.rand(10)
z = np.sqrt(x**2 y**2)
fig, axs = plt.subplots(2, 3, sharex=True, sharey=True)
# 符号标记
axs[0, 0].scatter(x, y, s=80, c=z, marker=">")
axs[0, 0].set_title("marker='>'")
# TeX 标记
axs[0, 1].scatter(x, y, s=80, c=z, marker=r'$alpha$')
axs[0, 1].set_title(r"marker=r'$alpha$'")
# 基于路径的标记
verts = [[-1, -1], [1, -1], [1, 1], [-1, -1]]
axs[0, 2].scatter(x, y, s=80, c=z, marker=verts)
axs[0, 2].set_title("marker=verts")
# 正多边形的标记
axs[1, 0].scatter(x, y, s=80, c=z, marker=(5, 0))
axs[1, 0].set_title("marker=(5, 0)")
# 常规星型标志
axs[1, 1].scatter(x, y, s=80, c=z, marker=(5, 1))
axs[1, 1].set_title("marker=(5, 1)")
# 常规星号标记
axs[1, 2].scatter(x, y, s=80, c=z, marker=(5, 2))
axs[1, 2].set_title("marker=(5, 2)")
plt.tight_layout()
plt.show()
plt.scatter
或ax.scatter
:绘制散点图。 plt.tight_layout()[5]:自动调整子图参数,使之填充整个图像区域。
参数linestyle
参数linestyle[6]有如下设置值:
值 | 线型 |
---|---|
'-' 或 'solid' | 实线 |
'--' 或 'dashed' | 虚线 |
'-.' 或 'dashdot' | 点划线 |
':' 或 'dotted' | 虚线 |
'None' 或 ' ' 或 '' | 不画线 |
linestyle
参数color
参数color[7]可控制颜色,具体有如下选择
color
除了内置颜色以外,也可以使用
- 灰度(如
c = "0.80"
), - RGB(如
c = (1.0, 0.3, 0.5)
), - 十六进制颜色(如
c = "#009C8E"
)
对参数color
进行设置。下面绘制一系列子图以便理解设置颜色的各类方法:
datathin = data1d.thin(time=50)
fig, ax = plt.subplots(2,3, sharex=True, sharey=True, figsize = (12, 4))
fig.subplots_adjust(hspace = 0.5, wspace = 0.2)
datathin.plot(ax = ax[0,0], c = "black")
ax[0,0].set_title('c = "black"')
datathin.plot(ax = ax[0,1], c = "r")
ax[0,1].set_title('c = "r"')
datathin.plot(ax = ax[0,2], c = "0.80")
ax[0,2].set_title('c = "0.80"')
datathin.plot(ax = ax[1,0], c = "#009C8E")
ax[1,0].set_title('c = "#009C8E"')
datathin.plot(ax = ax[1,1], c = (1.0, 0.3, 0.5))
ax[1,1].set_title('c = (1.0, 0.3, 0.5)')
datathin.plot(ax = ax[1,2], c = "orchid")
ax[1,2].set_title('c = "orchid"')
for axi in ax.flat:
axi.set_ylabel("");
for axi in ax.flat:
通过迭代器ax.flat
对高维Axes
数组ax
迭代,获取每一个子图的Axes
信息,在每一个循环过程中将各个Axes
的地址赋值给axi
(按址赋值),然后通过变量axi
控制各个子图的绘图属性。
如上述代码将各个子图的
轴坐标标签赋值为无字符串形式,即axi.set_ylabel("")
.
若要显式查看各个Axes
情况可通过ax.flatten()
实现
- 默认绘图:未设置
axi.set_ylabel("")
子图绘制情况
- 已设置
axi.set_ylabel("")
子图绘制情况
参考资料
[1]
CF规范: http://cfconventions.org/Data/cf-conventions/cf-conventions-1.7/build/ch03s03.html
[2]
MATLAB 线图绘制: https://ww2.mathworks.cn/help/matlab/ref/plot.html
[3]
matplotlib.markers: https://matplotlib.org/stable/api/markers_api.html
[4]
Matlibplot 官网: https://matplotlib.org/stable/gallery/lines_bars_and_markers/scatter_star_poly.html
[5]
plt.tight_layout(): https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.tight_layout.html
[6]
linestyle: https://matplotlib.org/stable/api/_as_gen/matplotlib.lines.Line2D.html#matplotlib.lines.Line2D.set_linestyle
[7]
color: https://matplotlib.org/stable/api/colors_api.html
TIPS