您可以与 plotly.express 共享两个子面板之间的图形滑块吗?

Can you share a figure slider between two subpanels with plotly.express?

我想要一个带有两个子图的图形,它们都使用相同的 x 轴滑块和 plotly.express 进行更新。

我已经使用如下命令成功完成了带有滑块的单个子图:

import plotly.express as px

px.line(plot_df, x='context', y='probability',animation_frame='trial',animation_group='t', color="t", range_y=[0,1])

但我不知道如何将其扩展为由同一个滑块控制两个子图,或者这是否可能。我显然可以以相同的方式添加另一个子图,但帧不会同步更新。有什么建议么?谢谢。

编辑

问题不是很清楚,所以我提供示例数据和额外描述:

# Example Data for plot A
npi = 8
nc = 4
data = np.zeros([npi,nc,t])
for c in range(nc):
    data[:,c,:] = np.tile(np.arange(npi).reshape(npi,1),t) +     np.random.normal(0,2,size=[npi,t])

pols = np.arange(npi)
ts = np.arange(t)
cs = np.arange(nc)

mi = pd.MultiIndex.from_product([pols, cs, ts], names=['policy', 'context', 'trial'])
df = pd.Series(index=mi, data=data.flatten())
df = df.reset_index().rename(columns = {0:'probability'})

# Desired animation for plot A
px.line(df, x='policy', y='probability',animation_frame='trial',animation_group='context', color="context")

# Example Data for plot B
t = 10
nc = 6
tau = 4
data = np.zeros([nc,tau,t])
for ti in range(tau):
    data[:,ti,:] = np.tile(np.arange(nc).reshape(nc,1),t) + np.random.normal(0,2,size=[nc,t])

conts = np.arange(nc)
ts = np.arange(t)
taus = np.arange(tau)

mi = pd.MultiIndex.from_product([conts, taus, ts], names=['context', 'timepoint', 'trial'])
df = pd.Series(index=mi, data=data.flatten())
df = df.reset_index().rename(columns = {0:'probability'})

# Desired animation for plot B
px.line(df, x='context', y='probability',animation_frame='trial',animation_group='timepoint', color="timepoint")

我想要一个图,其中子图 A 和 B 彼此相邻绘制并由相同的“试验”滑块控制,这样我就可以并排看到它们的演变。

  • 获取您的生成器代码。 fig1是第一个数字,fig2是第二个数字
  • 现在创建一个新图形,将两个图形的所有轨迹和帧集成在一起。对于第二个图中的轨迹/帧,将它们放在 x2 / y2
  • 终于搞定整合布局
import plotly.graph_objects as go

# integrate the two figures, putting second figure on separate axis
fig = go.Figure(
    data=[t for t in fig1.data] + [t.update(xaxis="x2", yaxis="y2") for t in fig2.data],
    frames=[
        go.Frame(
            name=fr1.name,
            data=[t for t in fr1.data]
            + [t.update(xaxis="x2", yaxis="y2") for t in fr2.data],
        )
        for fr2, fr1 in zip(fig2.frames, fig1.frames)
    ],
    layout=fig1.layout,
)

# now config axes appropriately
fig.update_layout(
    xaxis_domain=[0, 0.49],
    xaxis2={"domain": [0.51, 1], "matches": None, "title":{"text":fig2.layout.xaxis.title.text}},
    yaxis2={"matches":"y"},
    showlegend=False,
)


生成器代码

import pandas as pd
import numpy as np
import plotly.express as px

# Example Data for plot A
t = 10
npi = 8
nc = 4
data = np.zeros([npi,nc,t])
for c in range(nc):
    data[:,c,:] = np.tile(np.arange(npi).reshape(npi,1),t) +     np.random.normal(0,2,size=[npi,t])

pols = np.arange(npi)
ts = np.arange(t)
cs = np.arange(nc)

mi = pd.MultiIndex.from_product([pols, cs, ts], names=['policy', 'context', 'trial'])
df = pd.Series(index=mi, data=data.flatten())
df = df.reset_index().rename(columns = {0:'probability'})

# Desired animation for plot A
fig1 = px.line(df, x='policy', y='probability',animation_frame='trial',animation_group='context', color="context")

# Example Data for plot B
t = 10
nc = 6
tau = 4
data = np.zeros([nc,tau,t])
for ti in range(tau):
    data[:,ti,:] = np.tile(np.arange(nc).reshape(nc,1),t) + np.random.normal(0,2,size=[nc,t])

conts = np.arange(nc)
ts = np.arange(t)
taus = np.arange(tau)

mi = pd.MultiIndex.from_product([conts, taus, ts], names=['context', 'timepoint', 'trial'])
df = pd.Series(index=mi, data=data.flatten())
df = df.reset_index().rename(columns = {0:'probability'})

# Desired animation for plot B
fig2 = px.line(df, x='context', y='probability',animation_frame='trial',animation_group='timepoint', color="timepoint")

fig2