使用 xarray 多年的双 y 轴图,每月平均值作为 x 轴
Twin y axes plot with monthly average as x-axis over multiple years with xarray
感谢您对此感兴趣post。
我希望创建一个双 y 轴图来说明 2 个变量(例如 y1=snowmelt 和 y2=discharge 运行-off)。由于我对 python 的了解非常有限,因为我刚刚开始学习编码,所以我很困惑如何去做。
我能够构建一个双 y 轴图和一个代表多年月平均值的图。但是,我不确定如何将这些 matplotlib 代码组合在一起并创建一个双 y 轴图,其中月平均值作为多年的 x 轴。
月平均代码
disda = xr.open_mfdataset(sorted(['1980.nc','1981.nc', '1982.nc', '1983.nc','1984.nc','1985.nc','1986.nc','1987.nc', '1988.nc','1989.nc', '1990.nc', '1991.nc', '1992.nc', '1993.nc', '1994.nc', '1996.nc', '1997.nc', '1998.nc','1999.nc']))
snowdepth_we = xr.open_dataarray('Snow depth water equivalent.nc')
disyrs = disda.sel(time=slice('1981','1999'))
snyrs = snowdepth_we.sel(time=slice('1981','1999'))
dismonthlymean = disyrs.dis24
dislatlonmean = dismonthlymean.mean(dim=['latitude','longitude']).resample(time='M').sum()
snowlatlonmean = snmonthlymean.mean(dim=['latitude','longitude'])
disgroupby = dislatlonmean.groupby("time.month").mean("time")
sngroupby = snowlatlonmean.groupby("time.month").mean("time")
#graph commands
myfig, myax = plt.subplots(figsize=(12,6))
TYs = np.unique(dislatlonmean["time.year"])
disgroupby.plot.line('b-', color='blue', linestyle='-', linewidth=4, label='Discharge Mean')
for YY in TYs:
plt.plot(np.arange(1,13), dislatlonmean.sel(time=YY.astype("str")), 'b-', color='blue', alpha=0.2)
TYs = np.unique(dislatlonmean["time.year"])
sngroupby.plot.line('b-', color='red', linestyle='-', linewidth=4, label='Snowdepth Mean')
for YY in TYs:
plt.plot(np.arange(1,13), dislatlonmean.sel(time=YY.astype("str")), 'b-', color='blue', alpha=0.2)
myax.set_title('Western Himalayas Snow Depth and River Indus Discharge Run-off 1981-1999')
myax.set_ylabel('m of water equivalent')
myax.set_xlabel('Month')
myax.set_xticks(range(1, 13))
myax.set_xticklabels(['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sept','Oct','Nov','Dec'])
myax.grid()
myax.legend(['Discharge Mean','Snowdepth'])
因为这不是双 y 轴图,所以我无法将具有不同测量值的 2 个变量一起绘制,其中一个变量在图中成为一条平线,在另一个图的下方
另一方面,我能够使用这些命令创建双 y 轴图
disda_dis248199 = disda_dis24.loc['1981':'1999'].mean(dim=['latitude','longitude']).resample(time='M').mean()
snow8199 = snowdepth_we.loc['1981':'1999'].mean(dim=['latitude','longitude']).resample(time='M').mean()
x = disda_dis248199.time
y1 = snow8199
y2 = disda_dis248199
#plotting commands
fig, ax1 = plt.subplots(figsize=(14,8))
ax1.set_xlabel('Year')
ax1.set_ylabel('Snow depth water equivalent (m of w.e)')
ax1.plot(x, y1, color='red', label='River Discharge')
ax1.tick_params(axis='y', labelcolor='red')
ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
ax2.set_ylabel('River Discharge (m3s−1)') # we already handled the x-label with ax1
ax2.plot(x, y2, color='blue',alpha=0.4, label='Snow depth water equivalent')
ax2.tick_params(axis='y', labelcolor='blue')
fig.legend(loc="upper right")
ax1.set_title('Western Himalayas Snow Depth and River Indus Tributaries Comparison 1981 - 2016')
ax2.grid()
我曾尝试将这两个命令合并在一起,但无济于事。
因此,我想知道是否有任何方法可以像第二张图一样绘制双 y 轴图,但以月为 x 轴,并且图中的两条线将代表 2 个不同的变量。
此外,正如您在图 1 中看到的那样,不知何故,图例仅显示了 1981-1999 年的排放平均值(粗线)和实际年平均值(细线),因此,我想知道我将如何能解决这个问题吗?
非常感谢您的帮助!!如果您需要更多信息,请告诉我,我会尽快回复。
由于您只提供了部分代码,我无法运行,因此也无法为您更改。但是,我将尝试对第一段代码中应该更改的内容进行解释。
作为第一步,您想要定义第二个 Axes
object,类似于您在第二段代码中的做法:
myax2 = myax.twinx()
由于您现在有两个 Axes
实例,因此您需要指定要在哪个 Axes
实例(myax
或 myax2
上绘制数据。这意味着而不是
disgroupby.plot.line('b-', color='blue', linestyle='-', linewidth=4, label='Discharge Mean')
sngroupby.plot.line('b-', color='red', linestyle='-', linewidth=4, label='Snowdepth Mean')
你应该做一些事情,比如
disgroupby.plot.line('b-', ax=myax, color='blue', linestyle='-', linewidth=4, label='Discharge Mean')
sngroupby.plot.line('b-', ax=myax2, color='red', linestyle='-', linewidth=4, label='Snowdepth Mean')
请注意在(关键字)参数列表中添加了 ax=...
。有关示例,请参见 this part of xarray's documentation。此外,您不再希望使用 plt.plot
,因为它没有指定在哪个 Axes
实例上绘制数据。相反,您想调用要在其上绘制数据的 Axes
实例的 plot
方法。例如,
的第一次出现
plt.plot(np.arange(1,13), dislatlonmean.sel(time=YY.astype("str")), 'b-', color='blue', alpha=0.2)
应该改为
myax.plot(np.arange(1,13), dislatlonmean.sel(time=YY.astype("str")), 'b-', color='blue', alpha=0.2)
第二次出现应该改为
myax2.plot(np.arange(1,13), dislatlonmean.sel(time=YY.astype("str")), 'b-', color='blue', alpha=0.2)
设置标签、标题等与您在第二段代码中的操作类似。
关于您的 plt.plot
语句的小提示,您的参数列表中有 ..., 'b-', color='blue', ...
。虽然这有效,但您指定了两次颜色。您可以删除 color='blue'
部分或将 'b-'
更改为 '-'
.
感谢您对此感兴趣post。
我希望创建一个双 y 轴图来说明 2 个变量(例如 y1=snowmelt 和 y2=discharge 运行-off)。由于我对 python 的了解非常有限,因为我刚刚开始学习编码,所以我很困惑如何去做。
我能够构建一个双 y 轴图和一个代表多年月平均值的图。但是,我不确定如何将这些 matplotlib 代码组合在一起并创建一个双 y 轴图,其中月平均值作为多年的 x 轴。
月平均代码
disda = xr.open_mfdataset(sorted(['1980.nc','1981.nc', '1982.nc', '1983.nc','1984.nc','1985.nc','1986.nc','1987.nc', '1988.nc','1989.nc', '1990.nc', '1991.nc', '1992.nc', '1993.nc', '1994.nc', '1996.nc', '1997.nc', '1998.nc','1999.nc']))
snowdepth_we = xr.open_dataarray('Snow depth water equivalent.nc')
disyrs = disda.sel(time=slice('1981','1999'))
snyrs = snowdepth_we.sel(time=slice('1981','1999'))
dismonthlymean = disyrs.dis24
dislatlonmean = dismonthlymean.mean(dim=['latitude','longitude']).resample(time='M').sum()
snowlatlonmean = snmonthlymean.mean(dim=['latitude','longitude'])
disgroupby = dislatlonmean.groupby("time.month").mean("time")
sngroupby = snowlatlonmean.groupby("time.month").mean("time")
#graph commands
myfig, myax = plt.subplots(figsize=(12,6))
TYs = np.unique(dislatlonmean["time.year"])
disgroupby.plot.line('b-', color='blue', linestyle='-', linewidth=4, label='Discharge Mean')
for YY in TYs:
plt.plot(np.arange(1,13), dislatlonmean.sel(time=YY.astype("str")), 'b-', color='blue', alpha=0.2)
TYs = np.unique(dislatlonmean["time.year"])
sngroupby.plot.line('b-', color='red', linestyle='-', linewidth=4, label='Snowdepth Mean')
for YY in TYs:
plt.plot(np.arange(1,13), dislatlonmean.sel(time=YY.astype("str")), 'b-', color='blue', alpha=0.2)
myax.set_title('Western Himalayas Snow Depth and River Indus Discharge Run-off 1981-1999')
myax.set_ylabel('m of water equivalent')
myax.set_xlabel('Month')
myax.set_xticks(range(1, 13))
myax.set_xticklabels(['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sept','Oct','Nov','Dec'])
myax.grid()
myax.legend(['Discharge Mean','Snowdepth'])
因为这不是双 y 轴图,所以我无法将具有不同测量值的 2 个变量一起绘制,其中一个变量在图中成为一条平线,在另一个图的下方
另一方面,我能够使用这些命令创建双 y 轴图
disda_dis248199 = disda_dis24.loc['1981':'1999'].mean(dim=['latitude','longitude']).resample(time='M').mean()
snow8199 = snowdepth_we.loc['1981':'1999'].mean(dim=['latitude','longitude']).resample(time='M').mean()
x = disda_dis248199.time
y1 = snow8199
y2 = disda_dis248199
#plotting commands
fig, ax1 = plt.subplots(figsize=(14,8))
ax1.set_xlabel('Year')
ax1.set_ylabel('Snow depth water equivalent (m of w.e)')
ax1.plot(x, y1, color='red', label='River Discharge')
ax1.tick_params(axis='y', labelcolor='red')
ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
ax2.set_ylabel('River Discharge (m3s−1)') # we already handled the x-label with ax1
ax2.plot(x, y2, color='blue',alpha=0.4, label='Snow depth water equivalent')
ax2.tick_params(axis='y', labelcolor='blue')
fig.legend(loc="upper right")
ax1.set_title('Western Himalayas Snow Depth and River Indus Tributaries Comparison 1981 - 2016')
ax2.grid()
我曾尝试将这两个命令合并在一起,但无济于事。
因此,我想知道是否有任何方法可以像第二张图一样绘制双 y 轴图,但以月为 x 轴,并且图中的两条线将代表 2 个不同的变量。
此外,正如您在图 1 中看到的那样,不知何故,图例仅显示了 1981-1999 年的排放平均值(粗线)和实际年平均值(细线),因此,我想知道我将如何能解决这个问题吗?
非常感谢您的帮助!!如果您需要更多信息,请告诉我,我会尽快回复。
由于您只提供了部分代码,我无法运行,因此也无法为您更改。但是,我将尝试对第一段代码中应该更改的内容进行解释。
作为第一步,您想要定义第二个 Axes
object,类似于您在第二段代码中的做法:
myax2 = myax.twinx()
由于您现在有两个 Axes
实例,因此您需要指定要在哪个 Axes
实例(myax
或 myax2
上绘制数据。这意味着而不是
disgroupby.plot.line('b-', color='blue', linestyle='-', linewidth=4, label='Discharge Mean')
sngroupby.plot.line('b-', color='red', linestyle='-', linewidth=4, label='Snowdepth Mean')
你应该做一些事情,比如
disgroupby.plot.line('b-', ax=myax, color='blue', linestyle='-', linewidth=4, label='Discharge Mean')
sngroupby.plot.line('b-', ax=myax2, color='red', linestyle='-', linewidth=4, label='Snowdepth Mean')
请注意在(关键字)参数列表中添加了 ax=...
。有关示例,请参见 this part of xarray's documentation。此外,您不再希望使用 plt.plot
,因为它没有指定在哪个 Axes
实例上绘制数据。相反,您想调用要在其上绘制数据的 Axes
实例的 plot
方法。例如,
plt.plot(np.arange(1,13), dislatlonmean.sel(time=YY.astype("str")), 'b-', color='blue', alpha=0.2)
应该改为
myax.plot(np.arange(1,13), dislatlonmean.sel(time=YY.astype("str")), 'b-', color='blue', alpha=0.2)
第二次出现应该改为
myax2.plot(np.arange(1,13), dislatlonmean.sel(time=YY.astype("str")), 'b-', color='blue', alpha=0.2)
设置标签、标题等与您在第二段代码中的操作类似。
关于您的 plt.plot
语句的小提示,您的参数列表中有 ..., 'b-', color='blue', ...
。虽然这有效,但您指定了两次颜色。您可以删除 color='blue'
部分或将 'b-'
更改为 '-'
.