Выпадающий виджет Python - PullRequest
0 голосов
/ 27 апреля 2020

Пожалуйста, потерпите меня. Первый пост для меня здесь. Я использую Python, первый язык программирования для меня, около двух недель. Теперь я застрял ..

Я хочу создать один график с выпадающим виджетом. На оси X я хочу выбрать выбранный год, а на оси Y - соответствующее число для этого года. Итак, 2009 год по оси X и 130 по оси Y и т. Д.

Я пробовал разные вещи, в основном играл три часа ..

Может быть, кто-то может мне помочь решение? Спасибо!

%matplotlib inline

import ipywidgets as widgets
from IPython.display import display
import seaborn as sns
import matplotlib.pyplot as plt
sns.set_style("darkgrid")

dropdown = widgets.Dropdown(
    options=['2009', '2010', '2011', "2012", "2013", "2014", "2015", "2016", "2017", "2018","2019"],
    value='2009',
    description='Jahr:',
    )

def Dropdown_Menu(b):

    fig, ax = plt.subplots()
    fig.dpi = 500

    x = [2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019]
    y = [130, 137, 104, 147, 401, 274, 234, 770, 857, 746, 704]

    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()

dropdown.observe(Dropdown_Menu, names="value")    
display(dropdown)

1 Ответ

0 голосов
/ 28 апреля 2020

dropdown выполняет Dropdown_Menu с выбранным value, но не будет выбирать значения из списка x,y. Вы должны сделать это.

По некоторым причинам dropdown.observe() не работает для меня, поэтому я использовал widgets.interact()

РЕДАКТИРОВАТЬ: кажется dropdown.observe() работает только в juputer notebook, но не в jupyter lab (который я использую), и для работы потребуется виджет Output(). Если вы будете использовать dropdown.observe(), то в Dropdown_Menu вам придется использовать 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)

РЕДАКТИРОВАТЬ: аналогичный код с ipympl что дает interactive plot - таким образом, ему не нужно заново и все повторять график, но он может заменить только строку (и) (удалить старую линию и построить новую линию), или он может заменить только данные, используемые в строке (без строки удаления)

%matplotlib widget 
# 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) 
...