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 ответа:
Я думаю, что вы неправильно поняли концепцию подзаголовков, причина, по которой вы получаете ошибку, заключается в том, что функция
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')
Спасибо
Так много для Нарен Мурали за вашу помощь! Редактирование вашего кода немного дало мне ответ.