Stacked Bar Chart with a Line on Dash with Python

I have a stacked bar chart and I need to overlay a line across it. Anyone have any insight?

When I add go.Scatter to the list in the data value it does not show up.

Any help would be great.

@app.callback(
    dash.dependencies.Output('indicator-graphic', 'figure'),
    [dash.dependencies.Input('my-dropdown', 'value'),
     dash.dependencies.Input('my-dropdown1', 'value')])
def update_output(value, value1):
    df['Date'] = pd.to_datetime(df['Date'])
    dff = df.set_index('Date')
    dff = dff.loc[value:value1]
    fr = dff.reset_index().pivot("Date", "Fund", "Strat_Ret")
    br = dff.reset_index().pivot("Date", "Fund", "Bench_Ret")
    fw = dff.reset_index().pivot("Date", "Fund", "Strat_Weight")
    bw = dff.reset_index().pivot("Date", "Fund", "Bench_Weight")
    _barfund_select = att.component(fr, br, fw, bw, 'asset')
    _barasset_select = att.component(fr, br, fw, bw, 'ass')
    fund_select = att.attribution(fr, br, fw, bw, 'asset')
    return {'data' : [go.Bar(
            {'x': _barfund_select.index, 'opacity':'.6'},
            y = _barfund_select[i].values,
            name = i) for i in _barfund_select.columns
        ],
        'layout': {
        'barmode':'stack',
        'filename':'bar-line',
        'showlegend': False,
        'hovermode': 'closest',
        "xaxis": {"tickfont": {"color": "rgb(68, 68, 68)"},
        "title": "",
        "ticks": "outside",
        "gridcolor": "rgb(255, 255, 255)",
        "showline": "true",
        "type": "date",
        "autorange": "false"},
        "yaxis": {"title": "", "ticks": "outside", "gridcolor": "rgb(255, 255, 255)", "showline": "true", "nticks": 11, "type": "linear", "autorange": "false", "tickformat":".1%"},
        "plot_bgcolor": "rgb(217, 224, 236)",
        "font": {"family": "Raleway"},
        "margin": {"r": 10, "b": 30, "pad": 0, "l": 40, "t": 30},
        }
    }

Check out https://plot.ly/python/graphing-multiple-chart-types/#line-chart-and-a-bar-chart for a simple example of a bar chart with a line chart. If you need horizontal lines that are positioned in the y-axis according to data points but are always across the entire xaxis canvas (regardless of the data), then check out the line shapes: https://plot.ly/python/shapes/#vertical-and-horizontal-lines-positioned-relative-to-the-axes

1 Like

Thanks, I figured it out. Such a great product. Convincing my firm to move away from Tableau.

2 Likes

@mikedoh89 - Interesting! I’ve been following plotly for a while and I agree that it has the kind of power to replace such tools. My main problem with Tableau is the inaccessibility. Who wants to tell their viewers that you have to license a reader app before you can enjoy the plots you created.

1 Like

I have looked at those examples and I do not understand what to do.
those use the fig = go.Figure().
but in Dash using a callback it returns a dict {‘data’: data, ‘layout’: layout}
and in the callback it has:
@app.callback(
Output(‘graphname’, ‘figure’),

some guidance would be much appreciated.

Hi

Can you please share how you figured it out?

In case anyone else lands here - a minimal example, adapted from https://stackoverflow.com/a/67408651:

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

data = [["A", 320, 880, 10], ["B", 150, 450, 20], ["C", 250, 700, 30]]
df = pd.DataFrame(data, columns=["Letter", "Bar1", "Bar2", "Line"])

fig = make_subplots(specs=[[{"secondary_y": True}]])

# add line chart
fig.add_trace(
    go.Scatter(x=df["Letter"], y=df["Line"], name="Line", mode="lines"),
    secondary_y=True,
)

# add bar charts
for bar in ["Bar1", "Bar2"]:
    fig.add_trace(go.Bar(x=df["Letter"], y=df[bar], name=bar), secondary_y=False)
fig.update_layout(barmode="stack")

# Set axis titles
fig.update_xaxes(title_text="Letter")
fig.update_yaxes(title_text="Bar axis", secondary_y=False)
fig.update_yaxes(title_text="Line axis", secondary_y=True)

fig.show()
3 Likes