dropdown executes Dropdown_Menu with selected value but it will not select values from list x,y. You have to do it.
For some reasons dropdown.observe() doesn't works for me so I used widgets.interact()
EDIT: it seems dropdown.observe() works only in juputer notebook but not in jupyter lab (which I use) and it would need widget Output() to work. If you will use dropdown.observe() then in Dropdown_Menu you have to use value = value.new.
%matplotlib inline
import ipywidgets as widgets
from IPython.display import display
import matplotlib.pyplot as plt
dropdown = widgets.Dropdown(
#options=['2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019'],
#value='2009',
options=list(range(2009, 2020)), # integers instead of strings
value=2009, # integer instead of string
description='Jahr:',
)
def Dropdown_Menu(value=2009):
#print(type(value))
#value = int(value) # I dont have to convert if `Dropdown` uses integer values
fig, ax = plt.subplots()
fig.dpi = 150
x = [2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019]
y = [130, 137, 104, 147, 401, 274, 234, 770, 857, 746, 704]
# get all value for `year >= value`
#pairs = [(a,b) for a,b in zip(x, y) if a >= value] # use `==` to get only one value
#selected_x, selected_y = zip(*pairs)
# select values
pos = x.index(value)
selected_x = x[pos]
selected_y = y[pos]
print('x:', selected_x)
print('y:', selected_y)
ax.plot(selected_x, selected_y, label="Flugstunden pro Jahr", marker=".")
ax.legend()
ax.set_title("Flugstunden")
ax.set_xlabel("Jahr")
ax.set_ylabel("Flugstunden")
ax.set_facecolor((0.9,0.9,0.9))
#plt.show()
widgets.interact(Dropdown_Menu, value=dropdown)
#dropdown.observe(Dropdown_Menu, names="value")
#display(dropdown)
EDIT: similar code with ipympl which gives interactive plot - so it doesn't have to replot all again and again but it can replace only line(s) (remove old line and plot new line) or it can replace only data used in line (without removig line)
EDIT (2025):
As @Wayne suggested in comment below: currently can be used %matplotlib ipympl and it explocitly shows that it needs to install ipympl (so it doesn't need comment # needs ipympl in code).
And as @Wayne said: "%matplotlib widget is a leftover from a legacy time when JupyterLab and Jupyter Noebook didn't use the same things."
And link to basic example in ipympl doc (also from comment).
%matplotlib ipympl # explictly shows that it needs `ipympl`
# %matplotlib widget # still work as legacy but doesn't show that it needs `ipympl`
# needs ipympl
import ipywidgets as widgets
from IPython.display import display
import matplotlib.pyplot as plt
dropdown = widgets.Dropdown(
#options=['2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019'],
#value='2009',
options=list(range(2009, 2020)), # integers instead of strings
value=2009, # integer instead of string
description='Jahr:',
)
fig, ax = plt.subplots()
fig.dpi = 150
x = [2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019]
y = [130, 137, 104, 147, 401, 274, 234, 770, 857, 746, 704]
line, = ax.plot(x, y, label="Flugstunden pro Jahr", marker=".")
ax.legend()
ax.set_title("Flugstunden")
ax.set_xlabel("Jahr")
ax.set_ylabel("Flugstunden")
ax.set_facecolor((0.9,0.9,0.9))
#plt.show()
def on_change1(value=2009):
"""remove old line(s) and plot new line(s)"""
#print(type(value))
#value = int(value) # I don't have to convert string to integer
# get all value for `year >= value`
#pairs = [(a,b) for a,b in zip(x, y) if a >= value] # use `==` to get only one value
#selected_x, selected_y = zip(*pairs)
# select data
pos = x.index(value)
selected_x = x[pos] # create `selected_x` to keep original values in `x`
selected_y = y[pos] # create `selected_y` to keep original values in `y`
print('x:', selected_x)
print('y:', selected_y)
# remove old line(s)
for l in ax.lines:
l.remove()
# plot new line(s)
ax.plot(selected_x, selected_y, label="Flugstunden pro Jahr", marker=".")
def on_change2(value=2009):
"""keep line, remove all data from line and use new data with the same line"""
#print(type(value))
#value = int(value) # I don't have to convert string to integer
# get all value for `year >= value`
#pairs = [(a,b) for a,b in zip(x, y) if a >= value] # use `==` to get only one value
#selected_x, selected_y = zip(*pairs)
# select data
pos = x.index(value)
selected_x = x[pos] # create `selected_x` to keep original values in `x`
selected_y = y[pos] # create `selected_y` to keep original values in `y`
print('x:', selected_x)
print('y:', selected_y)
line.set_xdata(selected_x)
line.set_ydata(selected_y)
#fig.canvas.draw()
widgets.interact(on_change1, value=dropdown)
#widgets.interact(on_change2, value=dropdown)
Dropdown_Menuyou always use the same values inx,yso it will always draw the same plot. You have to filter values to get something different.