How to add custom buttons to update data in plotly graph

Hi,
I find plotly library is a veary goof library. I’m trying to build a graph like this one below, I’m just wandring if I can add custom buttons to refresh data on the graph.

for examle if I click the right arrow button I need to get the next six months (if exist) and when I click the left arrow button I need to get back the last six month (if exist). is this possible with plotly library please ?

thanks for your help.

HI @Youp,

Sorry, not sure I understand - do you want to know how to add buttons underneath the graph; or how to make the buttons change what’s displayed; or both?

  • To add buttons underneath, you can use the html.Button component, with some custom styling.
  • You could also use other libraries like Dash Bootstrap Components and Dash Mantine Components to help with the placement of the buttons and for nicer out-of-the-box styling.
  • To update the graph when buttons are clicked; you’d need to add a callback to each of the buttons. E.g. the left arrow button would filter the original data to just have the previous 6 months; the right arrow button would filter the data to just have the next 6 months.

I realise that’s a bit general - I can provide more detail as needed.

thanks for your time and effort.

  • do you want to know how to add buttons underneath the graph; or how to make the buttons change what’s displayed; or both?
  • => I want both, Could you please provide an example how I can combine plotly graph with [html.Button] ?
  • thanks

A bare-bones example of something that (I think) does what you’re describing:

# -------------------------------------------------------------------------------------------------
# Imports
# -------------------------------------------------------------------------------------------------
from dash import Dash, html, dcc, Input, Output, callback, ctx
import plotly.express as px
import pandas as pd
import numpy as np


# -------------------------------------------------------------------------------------------------
# App setup
# -------------------------------------------------------------------------------------------------
app = Dash()

# create some random time-series data, daily from 01-Jun-2024 to 31-Jul-2025
dates = pd.date_range(start="6/1/2024", end="07/31/2025")
values = np.random.default_rng().uniform(1, 10, len(dates))
df = pd.DataFrame({"dates": dates, "values": values})

# create a line graph of the data
fig = px.line(df, x="dates", y="values")

# set up the app layout
app.layout = html.Div(
    children=[
        # Header
        html.H1(children="Hello Dash"),

        # Time series line graph
        dcc.Graph(id="time-series-graph", figure=fig),

        # 2 x buttons: see https://dash.plotly.com/dash-html-components/button
        html.Div(
            [
                html.Button("Left", id="left-btn", n_clicks=0),
                html.Button("Right", id="right-btn", n_clicks=0)
            ]
        )
    ]
)

# -------------------------------------------------------------------------------------------------
# Callbacks to update the graph, see:
# - https://dash.plotly.com/basic-callbacks
# - https://dash.plotly.com/duplicate-callback-outputs
# -------------------------------------------------------------------------------------------------
@callback(
    Output("time-series-graph", "figure"),
    Input("left-btn", "n_clicks"),
    Input("right-btn", "n_clicks"),
    prevent_initial_call=True   # we don't want the callback to fire when the app loads initially
)
def update_graph(left_clicks, right_clicks):
    # The line below works out whether left-btn or right-btn was clicked to trigger the callback.
    # [Needs proper date filtering based on 'now' +/- 6 months; below is just a hack to illustate]
    triggered_id = ctx.triggered_id
    if triggered_id == "left-btn":
        ddf = df[df["dates"] < "2024-12-31"]
    elif triggered_id == "right-btn":
        ddf = df[df["dates"] > "2025-01-17"]

    return px.line(ddf, x="dates", y="values")


if __name__ == "__main__":
    app.run(debug=True)

I’ve only used standard Plotly here, not Dash Bootstrap Components or Dash Mantine Components, but they’ll work in a similar way.

The date filtering in the callback is just a very simple hack; you’ll need to add proper logic. But should help put you on the right path.

thanks for your time and effort…I tried to run this code to see how it looks the result but it gives me this error :

line 66, in 
    app.run(debug=True)
  File "/lib/python3.12/site-packages/dash/dash.py", line 2098, in run
    debug = self.enable_dev_tools(
            ^^^^^^^^^^^^^^^^^^^^^^
  File "/lib/python3.12/site-packages/dash/dash.py", line 1864, in enable_dev_tools
    _reload.watch_thread.start()
  File "/lib/python312.zip/threading.py", line 992, in start
    _start_new_thread(self._bootstrap, ())
RuntimeError: can't start new thread

I have tried this link to test : https://python-fiddle.com/examples/plotly?checkpoint=1737454305

Could you help please ?

When I run the fiddle in your link, I don’t get any errors?

It does say “you have unsaved changes” though - maybe that checkpoint isn’t up to date?