Python Plotly - несколько выпадающих графиков, каждый из которых имеет вложенные графики


Задача

Я пытаюсь объединить две функции Python Plotly. Одним из них является выпадающее меню, в котором пользователь может переключаться между сюжетами (ссылка на примеры). Другая особенность-это подзаголовки.

Моя попытка

У меня есть рабочий код, который использует выпадающее меню, но в нем нет вложенных диаграмм. Поэтому я посмотрел, как создавать подзаголовки здесь, и я подумал, что могу обращаться с фигурой tools.make_subplots так же, как я обращался с фигурой go.Box. Простите, если это покажется вам наивным, я ... на самом деле довольно новый для Плотли.

Однако эта попытка не работает вообще, я вижу два исключения, которые я поставил в самом низу.

Мой рабочий код (без подзаголовков)

# NOTE: This code goes in between 'START' and 'END' below
traces = []
for data in datas:
    traces.append(go.Box(
                            x=data.index,
                            y=data.values, 
                            showlegend=False
                        ))

Мой Код Подзаголовка

import plotly.offline as py
import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot, plot
from plotly import tools
init_notebook_mode(connected=True)

### Create individual figures
# START
traces = []
for data in datas:
    fig = tools.make_subplots(rows=1, cols=2)

    trace1 = go.Box(
                    x=data.head(10).index,
                    y=data.head(10).values, 
                    showlegend=False
                )
    trace2 = go.Box(
                    x=data.tail(10).index,
                    y=data.tail(10).values, 
                    showlegend=False
                )   
    fig.append_trace(trace1, 1, 1)
    fig.append_trace(trace2, 1, 2)
    traces.append(fig)
# END

### Create buttons for drop down menu
buttons = []
for i, label in enumerate(labels):
    visibility = [i==j for j in range(len(labels))]
    button = dict(
                 label =  label,
                 method = 'update',
                 args = [{'visible': visibility},
                     {'title': label}])
    buttons.append(button)

updatemenus = list([
    dict(active=-1,
         x=-0.15,
         buttons=buttons
    )
])

layout = dict(title='Title', 
              showlegend=False,
              updatemenus=updatemenus)

fig = dict(data=traces, layout=layout)

iplot(fig, filename='dropdown')

Ошибка 1

'layout' не допускается в 'scatter'

Путь к ошибке: ['data'][0] ['layout']

Ошибка 2

PlotlyError: недопустимый аргумент 'figure_or_data'. Плотли не будет
способен правильно проанализируйте полученный JSON. Если вы хотите отправить это 'figure_or_data' для построения графика в любом случае (не рекомендуется), вы можете установить 'validate=False' как вариант построения.

Вот почему вы видите эту ошибку:

'layout' не допускается в 'scatter'

...

Примечание: когда я передаю validate=False в качестве опции графика, все, что я вижу, - это пустой график с функцией выпадающего меню

2 2

2 ответа:

Я думаю, что вы неправильно поняли концепцию подзаголовков, причина, по которой вы получаете ошибку, заключается в том, что функция make_subplots() создаст собственный объект layout, следовательно, вы получаете ошибку.

'layout' is not allowed in 'scatter'

Path To Error: ['data'][0]['layout']

Правильный способ изменить макет подзаголовка-создать подзаголовок, получить доступ к отдельным свойствам объекта и задать их, как показано ниже.

updatemenus = list([
    dict(active=-1,
         x=-0.15,
         buttons=buttons
    )
])

fig['layout']['title'] = 'Title'
fig['layout']['showlegend'] = False
fig['layout']['updatemenus'] = updatemenus

Также вы создаете новый объект подзаголовка каждый раз, когда выполняется цикл for, что является неправильным. Я говоря о нижеследующей строке.

traces = []
for data in datas:
    fig = tools.make_subplots(rows=1, cols=2)

Вам нужно назначить его только один раз, пожалуйста, обратитесь к нижеприведенному рабочему примеру и попробуйте реализовать тот же метод для вашего usecase.

import plotly.offline as py
import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot, plot
from plotly import tools
init_notebook_mode(connected=True)
df = pd.DataFrame([[1, 2], [3, 4], [5, 6], [7, 8]], columns=["A", "B"])
labels = ["A", "B"]
datas = [df, df]
### Create individual figures
# START
fig = tools.make_subplots(rows=2, cols=2)

for i, data in enumerate(datas):

    trace1 = go.Bar(
                    x=data.head(10).A,
                    y=data.head(10).B, 
                    showlegend=False
                )
    trace2 = go.Bar(
                    x=data.tail(10).A,
                    y=data.tail(10).B, 
                    showlegend=False
                )   
    fig.append_trace(trace1, i + 1, 1)
    fig.append_trace(trace2, i + 1, 2)

### Create buttons for drop down menu
buttons = []
for i, label in enumerate(labels):
    visibility = [i==j for j in range(len(labels))]
    button = dict(
                 label =  label,
                 method = 'update',
                 args = [{'visible': visibility},
                     {'title': label}])
    buttons.append(button)

updatemenus = list([
    dict(active=-1,
         x=-0.15,
         buttons=buttons
    )
])

fig['layout']['title'] = 'Title'
fig['layout']['showlegend'] = False
fig['layout']['updatemenus'] = updatemenus

iplot(fig, filename='dropdown')
Пожалуйста, дайте мне знать, если это решит вашу проблему!

Нарен прав, нужно сделать только одну фигуру подзаголовка. И чтобы создать эффект выпадающего меню, вам просто нужно добавить две трассировки в одну и ту же позицию, как это..

fig.append_trace(trace1, 1, 1)
fig.append_trace(trace2, 1, 1)

Рабочий код

import plotly.offline as py
import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot, plot
from plotly import tools
init_notebook_mode(connected=True)

x = [i for i in range(100)]
df_1 = pd.DataFrame([(i, 1+i) for i in range(100)], columns=["X", "Y"])
df_2 = pd.DataFrame([(i, i*i) for i in range(100)], columns=["X", "Y"])
labels = ["Plus one", "Square"]

### Create individual figures
# START
fig = tools.make_subplots(rows=1, cols=2)

trace1 = go.Bar(
                x=df_1.head(10).X,
                y=df_1.head(10).Y, 
                showlegend=False
            )
trace2 = go.Bar(
                x=df_2.head(10).X,
                y=df_2.head(10).Y, 
                showlegend=False
            )

fig.append_trace(trace1, 1, 1)
fig.append_trace(trace2, 1, 1)

trace1 = go.Bar(
                x=df_1.tail(10).X,
                y=df_1.tail(10).Y, 
                showlegend=False
            )
trace2 = go.Bar(
                x=df_2.tail(10).X,
                y=df_2.tail(10).Y, 
                showlegend=False
            )   
fig.append_trace(trace1, 1, 2)
fig.append_trace(trace2, 1, 2)
# END

### Create buttons for drop down menu
buttons = []
for i, label in enumerate(labels):
    visibility = [i==j for j in range(len(labels))]
    button = dict(
                 label =  label,
                 method = 'update',
                 args = [{'visible': visibility},
                     {'title': label}])
    buttons.append(button)

updatemenus = list([
    dict(active=-1,
         x=-0.15,
         buttons=buttons
    )
])

fig['layout']['title'] = 'Title'
fig['layout']['showlegend'] = False
fig['layout']['updatemenus'] = updatemenus

iplot(fig, filename='dropdown')

Спасибо

Так много для Нарен Мурали за вашу помощь! Редактирование вашего кода немного дало мне ответ.

Я искал, чтобы создать это.. Введите описание изображения здесь Введите описание изображения здесь

Однако ваш код давал мне это график... Введите описание изображения здесь Введите описание изображения здесь