pythonplotlystreamlit

Two stacked area plots on the same chart


Plotting assets

I'm plotting $MSTR assets as follows

fig = px.area(df_all, x='end', y='val', color='fact', title=f'{symbol.upper()} : Balance sheet', width=1000, height=600)

fig.add_trace(go.Scatter(x=df_assets['end'], y=df_assets['val'], mode='lines', name='Assets'))

st.plotly_chart(fig)

enter image description here

Plotting liabilities

Similarly, I'm plotting liabilities like this (these show up as negative):

fig = px.area(df_all_liabilities, x='end', y='val', color='fact', title=f'{symbol.upper()} : Balance sheet', width=1000, height=600)

fig.add_trace(go.Scatter(x=df_liabilities['end'], y=df_liabilities['val'], mode='lines', name='Liabilities'))

st.plotly_chart(fig)

enter image description here

Question

Is there a way to have both of these on the same chart?


Solution

  • You can use plotly.graph_objects to add graphs in a loop process on a per-category basis, or you can reuse graph data created using px.area. I didn't have any data to reproduce for your question, so I used the examples in the reference to create a graph with subplots. By setting the spacing between the upper and lower graphs to zero, I made it look like a single graph. Depending on your data, some adjustments may be necessary.

    import plotly.express as px
    from plotly.subplots import make_subplots
    import plotly.graph_objects as go
    
    df = px.data.gapminder()
    df['pop2'] = df['pop']*-1
    
    fig_t = px.area(df, x="year", y="pop", color="continent", line_group="country")
    fig_b = px.area(df, x="year", y="pop2", color="continent", line_group="country")
    
    fig = make_subplots(rows=2, cols=1,
                        shared_xaxes=True,
                        vertical_spacing=0,
                        specs=[[{'type': 'scatter'}], [{'type': 'scatter'}]],
                       )
    
    for i in range(len(fig_t.data)):
        fig.add_trace(fig_t.data[i], row=1, col=1)
        
    for k in range(len(fig_b.data)):
        fig.add_trace(fig_b.data[k], row=2, col=1)
        
    fig.show()
    

    Area graph