在具有多个图的 relplot() 调用中引入第二个 y 轴

Introducing a second y axis into a relplot() call with multiple plots

问题

我有 2 个数据帧,我将它们合并然后与 pandas 融合。我需要对它们进行多重绘制(如下所示)并且代码需要可扩展。它们由 2 个变量 构成下面的 'key' 列(此处为 'x' 和 'y'),横跨 多个 'stations'(这里只有 2 个,但需要可扩展)。我已经使用 relplot() 能够在每个图表上绘制两个变量,并在不同的图表上绘制不同的站点。

有什么方法可以保持这种格式,但在每个图上引入第二个 y 轴? 'x' 和 'y' 需要在我的实际数据中处于不同的比例。我已经看到 ,其中 relplot 调用与 y = 1st variable 一起存储,并且为第二个变量添加了第二个线图调用,其中包含 ax.twinx()。因此,在下面的示例中,'x' 和 'y' 在同一张图上各有一个 y 轴。

我如何使用熔化的数据框(例如下面)使它工作,其中 'key' = 2 个变量并且 'station' 可以是长度 n?或者是废弃 df 格式并重新开始的答案?

示例代码

目前的多地块:

import numpy as np
np.random.seed(123)
date_range = pd.period_range('1981-01-01','1981-01-04',freq='D')
x = np.random.randint(1, 10, (4,2))
y = np.random.randint(1, 10, (4,2))
x = pd.DataFrame(x, index = date_range, columns = ['station1','station2'])
y = pd.DataFrame(y, index = date_range + pd.to_timedelta(1, unit="D"), columns = ['station1','station2'])

#keep information where each data point comes from
x["key"], y["key"] = "x", "y"
#moving index into a column 
x = x.reset_index()
y = y.reset_index()
#and changing it to datetime values that seaborn can understand
#necessary because pd.Period data is used
x["index"] = pd.to_datetime(x["index"].astype(str))
y["index"] = pd.to_datetime(y["index"].astype(str))

#combining dataframes and reshaping 
df = pd.concat([x, y]).melt(["index", "key"], var_name="station", value_name="station_value")

#plotting
fg = sns.relplot(data=df, x = "index", y = "station_value", kind = "line", hue = "key", row = "station")

#shouldn't be necessary but this example had too many ticks for the interval
from matplotlib.dates import DateFormatter, DayLocator
fg.axes[0,0].xaxis.set_major_locator(DayLocator(interval=1))
fg.axes[0,0].xaxis.set_major_formatter(DateFormatter("%y-%m-%d"))

plt.show()

你可以 relplot 只有一个 key(没有 hue),然后类似于链接线程,循环子图,创建一个 twinx,然后 lineplot第二个key/station组合:

#plotting
fg = sns.relplot(data=df[df['key']=='x'], x="index", y="station_value", kind="line", row="station")

for station, ax in fg.axes_dict.items():  
    ax1 = ax.twinx()
    sns.lineplot(data=df[(df['key'] == 'y') & (df['station'] == station)], x='index', y='station_value', color='orange', ci=None, ax=ax1)
    ax1.set_ylabel('')

输出:

不是你要求的,但你可以在不改变 df 形状的情况下制作具有不同 y-axes 的 relplots 网格

fg = sns.relplot(
    data=df,
    x = "index",
    y = "station_value",
    kind = "line",
    col = "key",
    row = "station",
    facet_kws={'sharey': False, 'sharex': True},
)