Search code examples
pythonpython-3.xplotlypanel

How to add python panel date range slider on_change event?


I am trying to use a dateRangeSlider to pick start and end dates and plot the graph accordingly using plotly in python.

Here, whenever I change the slider, how can I know that slider is updated (return currently selected date-range as tuple) and I need to update the plot X and Y axis ranges? Is there any event handler or a way to use a callback function?

Basically I want to know if dateRangeSlider is changed/updated and then I will pick the data in that range from a DataFrame and plot it using plotly.

EDIT: Added code with output image

import datetime as dt
import panel as pn
import yfinance as yf

pn.extension()

# Data part
vix_tickers = ['AUDJPY=X']

df = yf.download(vix_tickers,
                 auto_adjust=True, #only download adjusted data
                 progress=False,
            )
df = df[["Close"]]

# Date Range Slider
date_range_slider = pn.widgets.DateRangeSlider(
    name='Date Range Slider',
    sizing_mode="stretch_width",
    margin = [10,40],
    bar_color = "blue",
    start=df.index[0], end=df.index[-1],
    value=(df.index[0], df.index[-1]),
)

# A Plot
import plotly.graph_objs as go

fig = go.Figure()
df.sort_index(ascending=True, inplace=True)

trace = go.Scatter(x=list(df.index), y=list(df.Close))
fig.add_trace(trace)

fig.update_layout(
    dict(
        title="Time series with range slider and selectors",
        xaxis=dict(
            rangeselector=dict(
                buttons=list(
                    [
                        dict(count=1, label="1m", step="month", stepmode="backward"),
                        dict(count=6, label="6m", step="month", stepmode="backward"),
                        dict(count=1, label="YTD", step="year", stepmode="todate"),
                        dict(count=1, label="1y", step="year", stepmode="backward"),
                        dict(step="all"),
                    ]
                )
            ),
            rangeslider=dict(visible=False),
            type="date",
        ),
    )
)
fig.show()

date_range_slider

enter image description here


Solution

  • Please use ipywidgets instead of panel, it is easier and more powerful:

    import datetime as dt
    import pandas as pd
    import yfinance as yf
    import plotly.graph_objs as go
    from ipywidgets import interact
    from ipywidgets import widgets
    
    
    # Data part
    vix_tickers = ['AUDJPY=X']
    
    df = yf.download(vix_tickers,
                     auto_adjust=True, #only download adjusted data
                     progress=False,
                )
    df = df[["Close"]]
    
    df.sort_index(ascending=True, inplace=True)
    
    widgets.SelectionRangeSlider(
        options=df.index,
        description='Dates',
        orientation='horizontal',
        layout={'width': '1000px'}
        
        
    @interact
    def read_values(
        slider = widgets.SelectionRangeSlider(
        options=df.index,
         index=(0, len(df.index) - 1),
        description='Dates',
        orientation='horizontal',
        layout={'width': '500px'},
        continuous_update=False
    )
    ):
        fig = go.Figure()
        trace = go.Scatter(x=list(df.index), y=list(df.Close))
        fig.add_trace(trace)
        fig.update_xaxes(range=[slider[0], slider[1]])
        go.FigureWidget(fig.to_dict()).show()
    

    Output enter image description here