我很想同意这样的评论,即根据您的尝试表现出更多的努力会很好。最好提及您阅读的内容(例如 xarray 文档:https://xarray.pydata.org/en/stable/),我相信其中包含您需要的许多组件。
我将首先设置一些模拟数据,就像你提到的那样,包含四年的每日(随机)数据。
time = pd.date_range("2000-01-01", "2004-12-31")
base = xr.DataArray(
data=np.ones((time.size, 3, 2)),
dims=("time", "lat", "lon"),
coords={
"time": time,
"lat": [1, 2, 3],
"lon": [0.5, 1.5],
},
)
为了使数据与您的示例更具可比性,我将添加年度季节性(基于一年中的某天),并使每年增加 0.1。
seasonality = xr.DataArray(
data=np.sin((time.dayofyear / 365.0) * (2 * np.pi)),
coords={"time": time},
dims=["time"],
)
trend = xr.DataArray(
data=(time.year - 2000) * 0.1,
coords={"time": time},
dims=["time"],
)
da = base + seasonality + trend
(您显然可以跳过这两个部分,在您的情况下,您只需执行xarray.open_dataset() or xarray.open_dataarray`)
我不认为您的示例是按月份分组的:它太顺利了。因此,我将改为按年分组。
让我们从获取单个位置开始,然后使用 dt 访问器:
https://xarray.pydata.org/en/stable/time-series.html#datetime-components
在这种情况下,将数据存储为 DataFrame 也是最方便的,因为它本质上变成了一个表(以一年中的月份为行,单独的年份等为列)。首先我们选择一个位置,计算最小值和最大值并将它们存储在 pandas DataFrame 中:
location = da.isel(lat=0, lon=0)
dataframe = location.groupby(da["time"].dt.dayofyear).min().drop(["lat", "lon"]).to_dataframe(name="min")
dataframe["max"] = location.groupby(da["time"].dt.dayofyear).max().values
接下来,逐年抓取数据,并将其添加到 DataFrame:
for year, yearda in location.groupby(location["time"].dt.year):
dataframe[year] = pd.Series(index=yearda["time"].dt.dayofyear, data=yearda.values)
如果您想要每月值,请按步骤添加另一个分组:
for year, yearda in location.groupby(location["time"].dt.year):
monthly_mean = yearda.groupby(yearda["time"].dt.month).mean()
dataframe[year] = pd.Series(index=monthly_mean["month"], data=monthly_mean.values)
请注意,通过首先将数据转换为 pandas Series,它可以根据索引的值(此处为 dayofyear)适当地添加值,即使我们没有每年的 366 个值。
接下来,绘制它:
dataframe.plot()
它会根据列自动分配色调。
(由于我设置模拟数据的方式,我的最小值和最大值与 2000 年和 2004 年一致,......你明白了。)
在样式、选项等方面,你可能更喜欢 seaborn:
https://seaborn.pydata.org/index.html
import seaborn as sns
sns.plot(data=dataframe)
如果您想使用不同的样式、不同类型的图(例如您的示例具有的彩色区域),您必须组合不同的图,例如如下:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.fill_between(x=dataframe.index, y1=dataframe["min"], y2=dataframe["max"], alpha=0.5, color="orange")
dataframe.plot(ax=ax)
请注意,seaborn、pandas、xarray 等都在后台使用 matplotlib。许多绘图函数还接受 ax 参数,以在现有绘图的顶部绘图。