pythonplotplotlysubplot

Plotly: How to make subplots with multiple traces


I am plotting two figures in Plotly using this code:

d = {'1': pd.DataFrame({'x': [1,2,3], 'y': [2,4,6]}), '2': pd.DataFrame({'x': [2,4,6], 'y': [4,6,8]})}


def p1(df, n):
    x = df.x.tolist()
    y = df.y.tolist()
    y_upper = (2*df.y).tolist()
    y_lower = (0.5*df.y).tolist()

    fig = go.Figure([
        go.Scatter(
            x=x,
            y=y,
            mode='lines',
            name=n,
            showlegend=True
        ),
        go.Scatter(
            x=x+x[::-1],
            y=y_upper+y_lower[::-1],
            fill='toself',
            line=dict(color='rgba(255,255,255,0)'),
            hoverinfo='skip',
            showlegend=False
        )
    ])
    return fig


def p2():
    fig_data = tuple(p1(df, n).data for n, df in d.items())
    fig = go.Figure(sum(zip(*fig_data), ()))
    fig.update_layout(xaxis=dict(range=[0, 5],
                                 showgrid=True),
                      yaxis=dict(showgrid=True))
    return fig


def p3():    
    fig = go.Figure()
    for (n, df) in d.items():
        y = df.iloc[1]
        fig.add_trace(go.Bar(
            x=['x', 'y', 'z'],
            y=y,
            name=n,
            text=y,
            textposition='outside'
        ))
    fig.update_layout(bargroupgap=0.1, barmode='group')
    return fig

I want to plot these two figures in subplots, and I follow the example on the official Plotly site:

from plotly.subplots import make_subplots
import plotly.graph_objects as go

fig = make_subplots(rows=1, cols=2)

fig.add_trace(
    p3().data[0],
    row=1, col=1
)

fig.add_trace(
    p2().data[0],
    row=1, col=2
)

fig.update_layout(height=600, width=800, title_text="Side By Side Subplots")
fig.show()

This doesn't work through as my figures have more than just the data[0]-element. Is there a way to include all data-elements of the two plots in the subplot?


Solution

  • You could add each trace in a loop.

    fig = make_subplots(rows=1, cols=2)
    
    for trace in p3().data:
        fig.add_trace(trace,
                      row=1, col=1
                      )
    
    for trace in p2().data:
        fig.add_trace(trace,
                      row=1, col=2
                      )
    
    fig.update_xaxes(p2().layout.xaxis, col=2, row=1)
    fig.update_yaxes(p2().layout.yaxis, col=2, row=1)
    fig.update_layout(p3().layout)
    
    fig.update_layout(height=600, width=800, title_text="Side By Side Subplots")
    fig.show()
    

    fig