Dynamically slice a dataframe using Matplotlib dropdown widget

49 Views Asked by At

I have the following code adapted from this blog to slice a dataframe based on the selected values of two dropdown widgets, then updated the graph with the new data.

This is my code

import numpy as np
import pandas as pd
import ipywidgets as widgets
from matplotlib import pyplot as plt
import matplotlib.dates as dates
%matplotlib widget

df = pd.DataFrame({'Date': ['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04', '2023-01-05'],
                   'EUR': [0.636805, 0.637249, 0.637676, 0.642802, 0.643764],
                   'JPY': [89.564402, 89.217571, 88.275751, 89.122584, 90.270398], 
                   'USD': [0.680616, 0.680714, 0.676402, 0.681486, 0.681911]
                    })

df['Date'] = pd.to_datetime(df['Date'])

output = widgets.Output()

x = df[['Date', 'USD']]

with output:
    fig, ax = plt.subplots(constrained_layout=True, figsize=(6, 4))
    line, = ax.plot(x['Date'], x['USD'])

dropdown_1 = widgets.Dropdown(
    value=pd.to_datetime('2023-01-01'), 
    options=df['Date'].values, 
    description='Start Date',
)

dropdown_2 = widgets.Dropdown(
    value=pd.to_datetime('2023-01-05'), 
    options=df['Date'].values,     
    description='End Date',
)     

def update_graph(start, end):
    # Find the locations of the new dates obtained from the dropdowns
    start_idx = x.index[x['Date'] == start.new].tolist()[0]
    end_idx = x.index[x['Date'] == end.new].tolist()[0]
    # Dynamically change the data to plot
    line.set_data(x[start_idx:end_idx])  
    fig.canvas.draw()

dropdown_1.observe(update_graph, 'value')
dropdown_2.observe(update_graph, 'value')
widgets.VBox([dropdown_1, dropdown_2])

However, the graph didn't update with the new data when I changed the values of the dropdown widgets.

Could someone please tell me what I did wrong?

0

There are 0 best solutions below