Python可视化 | xarray一维数据绘图

2021-08-26 17:14:04 浏览数 (1)

代码语言:javascript复制
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()方法绘图

代码语言:javascript复制
data1d.plot()

data1d.plot()

似乎图在水平方向上稍显拥挤,有办法使得画板水平方向更加宽松吗?当然有。参数figsize可设置画板尺寸。既然可以调整画板尺寸,那么画板纵横比的调整便不难实现啦。下面给出一个实例:

代码语言:javascript复制
data1d.plot(figsize = (10,4), marker="o")

.plot()方法中的参数figsize本质传递给了底层plt.figure. 若以脚本层绘图方法有如下理解:

代码语言:javascript复制
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_namestandard_nameunits符合CF 规范[1]。xarray 数据的属性可用.attrs方法获取。

代码语言:javascript复制
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分别指定上述属性。

代码语言:javascript复制
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.scatterax.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进行设置。下面绘制一系列子图以便理解设置颜色的各类方法:

代码语言:javascript复制
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控制各个子图的绘图属性。

如上述代码将各个子图的

y

轴坐标标签赋值为无字符串形式,即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

0 人点赞