✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚡️ Concerned about the grid? Kyle Baranko teaches how to predicting peak loads using XGBoost. Register for the August webinar!

Constant red line across bar chart with multiple traces

I want a red line to go across my bar charts without scrunching the bars together. The red line should go across both charts at the average. This is just an MRE. The chart I’m actually using is 7 dropdowns the vary in size so the bars not scrunching together is very important to me.

import plotly.graph_objects as go

x1 = [‘Alfred’, ‘Bob’, “Cory”, “Dave”, “Eric”, "Freddy]
x2 = [‘Annie’, “Barbara”]

y1 = [20, 30, 25, 40, 40, 50]
y2 = [50, 70]

average = 47

fig = go.Figure()

fig.add_trace(go.Bar(x=x1, y=y1))
fig.add_trace(go.Bar(x=x2, y=y2, visible=False))

fig.add_shape(
type=‘line’, line=dict(dash=‘dot’, color=‘red’),
x0=-1, x1=len(x1), y0=average, y1=average
)

fig.update_layout(
updatemenus=[go.layout.Updatemenu(
active=0,
buttons=list([
dict(label=“1”,
method=“update”,
args=[{‘visible’:[False,True]}]),
dict(label=“2”,
method=“update”,
args=[{‘visible’:[True,False]}]),]))])

1 Like

Hi @ngpsu22, I tried to get this to work for a while, but I couldn’t. I think though you’ll be better off using Dash if you want to have an interactive app, it’s much easier to do things. Here’s I think what you want, but written in Dash. Also note you can use xref=paper to make the line span the plot axis instead of referencing data (so the line will always be there when you move the plot).

import plotly.graph_objects as go
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State

x = [["Alfred", "Bob", "Cory", "Dave", "Eric", "Freddy"], ["Annie", "Barbara"]]

y = [[20, 30, 25, 40, 40, 50], [50, 70]]

average = 47


def make_figure(dataset):
    fig = go.Figure()
    fig.add_trace(go.Bar(x=x[dataset], y=y[dataset]))
    fig.add_shape(
        type="line",
        line=dict(dash="dot", color="red"),
        x0=0,
        x1=1,
        xref="paper",
        y0=average,
        y1=average,
    )
    return fig


app = dash.Dash(__name__)
app.layout = html.Div(
    [
        dcc.Dropdown(
            id="dropdown",
            options=[{"label": 1, "value": 0}, {"label": 2, "value": 1}],
            value=0,
        ),
        dcc.Graph(id="graph"),
    ]
)


@app.callback(Output("graph", "figure"), [Input("dropdown", "value")])
def update_figure(value):
    return make_figure(value)


if __name__ == "__main__":
    app.run_server(debug=True)
2 Likes

Thanks so much for all the effort, I think it’s time for me to lean into Dash once and for all.

1 Like