Jupyter: Как я могу интерактивно выбрать серию для построения графика с использованием виджетов. SelectMultiple ()? - PullRequest
0 голосов
/ 11 февраля 2019

Справочная информация:

Аналогичный вопрос был задан здесь , но он не был очень конкретным, и на него в основном отвечали только ссылки на другие источники.Мой случай кажется довольно простым, и я удивлен тем, как трудно было найти рабочие примеры этого.

Цель:

Я просто хотел бы иметь возможностьчтобы выбрать любое подмножество из фрейма данных Pandas, чтобы создать график, как показано ниже, используя виджет, подобный этому:

enter image description here

Мои попытки:

Виджет widgets.SelectMultiple() кратко описан в документах , а в этом разделе описано, как можно интерактивно изменять значения для рядов на графике.Я попытался заменить центральные части последней демонстрации функциональностью widgets.SelectMultiple(), но без особого успеха.

Я думаю Я действительно близок к тому, чтобы заставить это работать, и я надеюсь Все, что мне нужно сделать, это выяснить, что написать в разделе, помеченном '# что делать!?' в фрагменте ниже.В настоящее время фрагмент кода создается, виджет и диаграмма создаются, но между ними нет функциональной связи.

Известные мне проблемы:

Мое воспроизведениепримеры, приведенные в ссылках, имеют некоторые недостатки.Я думаю, что df и widg должны быть включены в функцию multiplot.То же самое можно сказать и о функции interactive plot.Я тоже пробовал разные варианты, но безуспешно.

Фрагмент (используется в ноутбуке Jupyter):

# imports
%matplotlib inline

from ipywidgets import interactive
import pandas as pd
import numpy as np
from jupyterthemes import jtplot

# Sample data
np.random.seed(123)
rows = 50
dfx = pd.DataFrame(np.random.randint(90,110,size=(rows, 1)), columns=['Variable X'])
dfy = pd.DataFrame(np.random.randint(25,68,size=(rows, 1)), columns=['Variable Y'])
dfz = pd.DataFrame(np.random.randint(60,70,size=(rows, 1)), columns=['Variable Z'])

df = pd.concat([dfx,dfy,dfz], axis = 1)
#jtplot.style()

import ipywidgets as widgets
from IPython.display import display

def multiplot():
    opts = df.columns.values

    widg = widgets.SelectMultiple(
           options=opts,
           value=[opts[1]],
           rows=len(opts),
           description='Variables',
           disabled=False)

    display(widg)

    # what to do!? 
    df.plot()

    #attempts:
    #df[widg].plot()
    #df[widg.value[0]].plot()

interactive_plot = interactive(multiplot)
output = interactive_plot.children[-1]
output.layout.height = '350px'
interactive_plot

Вывод (недостатки):

enter image description here

1 Ответ

0 голосов
/ 11 февраля 2019

Спасибо за понятный пример.К сожалению, я не уверен, что SelectMultiple можно использовать так, как вы собираетесь.

Обычно для интерактивного вызова вам нужна функция, которой вы передаете аргументы.Вам не нужно создавать виджет внутри тела функции, вызов interact должен понять, какой тип входного виджета требуется из переданного параметра.

См. Здесь некоторые примеры, где вы указываете списокопций строки (https://ipywidgets.readthedocs.io/en/stable/examples/Using%20Interact.html#Widget-abbreviations)

Я сделал несколько небольших изменений в вашем коде, чтобы создать продукт взаимодействия с селектором Dropdown. Я подозреваю, что если вы хотите использовать SelectMultiple вместо Dropdown, это больше interact функциональность. Возможно, вам придется создать виджет отдельно, а затем использовать observe.

# imports
%matplotlib inline

from ipywidgets import interactive
import pandas as pd
import numpy as np
# from jupyterthemes import jtplot

# Sample data
np.random.seed(123)
rows = 50
dfx = pd.DataFrame(np.random.randint(90,110,size=(rows, 1)), columns=['Variable X'])
dfy = pd.DataFrame(np.random.randint(25,68,size=(rows, 1)), columns=['Variable Y'])
dfz = pd.DataFrame(np.random.randint(60,70,size=(rows, 1)), columns=['Variable Z'])

df = pd.concat([dfx,dfy,dfz], axis = 1)
#jtplot.style()

import ipywidgets as widgets
from IPython.display import display

def multiplot(a):
    opts = df.columns.values
    df.loc[:, a].plot()

interactive_plot = interactive(multiplot, a=['Variable X', 'Variable Y', 'Variable Z'])
output = interactive_plot.children[-1]
output.layout.height = '350px'
interactive_plot

enter image description here

А вот версия с использованием observe, виджет SelectMultiple и виджет Output:

# imports
%matplotlib inline

from ipywidgets import interactive
import pandas as pd
import numpy as np
from IPython.display import clear_output
import matplotlib.pyplot as plt

# Sample data
np.random.seed(123)
rows = 50
dfx = pd.DataFrame(np.random.randint(90,110,size=(rows, 1)), columns=['Variable X'])
dfy = pd.DataFrame(np.random.randint(25,68,size=(rows, 1)), columns=['Variable Y'])
dfz = pd.DataFrame(np.random.randint(60,70,size=(rows, 1)), columns=['Variable Z'])

df = pd.concat([dfx,dfy,dfz], axis = 1)
#jtplot.style()

import ipywidgets as widgets
from IPython.display import display

opts = df.columns.values

selector = widgets.SelectMultiple(
options=opts,
value=[opts[1]],
rows=len(opts),
description='Variables',
disabled=False)

output = widgets.Output()

display(selector)
display(output)

def multiplot(widg):
    choices = widg['new']
    data = df.loc[:, choices] if choices else df
    output.clear_output(wait=True)
    with output:
        ax = data.plot()
        plt.show()

selector.observe(multiplot, names='value')

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...