我有一个这样的数据框:
import pandas as pd
df = pd.DataFrame()
df['category'] = ['G1', 'G1', 'G1', 'G1','G1', 'G1','G1', 'G2', 'G2', 'G2', 'G2', 'G2', 'G2', 'G2']
df['date'] = ['2012-04-01', '2012-04-05', '2012-04-09', '2012-04-11', '2012-04-16', '2012-04-23', '2012-04-30',
'2012-04-01', '2012-04-05', '2012-04-09', '2012-04-11', '2012-04-16', '2012-04-23', '2012-04-30']
df['col1'] = [54, 34, 65, 67, 23, 34, 54, 23, 67, 24, 64, 24, 45, 89]
df['col2'] = round(df['col1'] * 0.85)
我想创建一个具有1 x(date
)和2 ys(col1
和col2
)的图形。像这样,通过类别下拉按钮,您可以选择类别并通过过滤所选类别的col1
和col2
数据来更新图形。
但是我无法使下拉菜单正常工作并更新行。
这是我尝试的代码:
# import plotly
from plotly.offline import init_notebook_mode, iplot, plot
import plotly.graph_objs as go
init_notebook_mode(connected=True)
x = 'date'
y1 = 'col1'
y2 = 'col2'
trace1 = {
'x': df[x],
'y': df[y1],
'type': 'scatter',
'mode': 'lines',
'name':'col 1',
'marker': {'color': 'blue'}
}
trace2={
'x': df[x],
'y': df[y2],
'type': 'scatter',
'mode': 'lines',
'name':'col 2',
'marker': {'color': 'yellow'}
}
data = [trace1, trace2]
# Create layout for the plot
layout=dict(
title='my plot',
xaxis=dict(
title='Date',
type='date',
tickformat='%Y-%m-%d',
ticklen=5,
titlefont=dict(
family='Old Standard TT, serif',
size=20,
color='black'
)
),
yaxis=dict(
title='values',
ticklen=5,
titlefont=dict(
family='Old Standard TT, serif',
size=20,
color='black'
)
)
)
# create the empty dropdown menu
updatemenus = list([dict(buttons=list()),
dict(direction='down',
showactive=True)])
total_codes = len(df.category.unique()) + 1
for s, categ in enumerate(df.category.unique()):
visible_traces = [False] * total_codes
visible_traces[s + 1] = True
updatemenus[0]['buttons'].append(dict(args=[{'visible': visible_traces}],
label='category',
method='update'))
updatemenus[0]['buttons'].append(dict(args=[{'visible': [True] + [False] * (total_codes - 1)}],
label='category',
method='update'))
layout['updatemenus'] = updatemenus
fig = dict(data = data, layout = layout)
iplot(fig)
我想使用category
列中的唯一组作为类别下拉按钮,然后选择category
(G1
或G2
)来过滤该数据并绘制出x
和ys
用于此所选类别。
我已经查看了位于plotly网站上的下拉页面,但是无法使下拉菜单正常工作。
答案 0 :(得分:1)
Plotly 3实现了ipython widgets
本机支持,因此我不确定他们是否正在维护其旧的窗口小部件。我建议使用ipython widgets
,因为它们更加标准和灵活,而且即使习惯了一些时间,我也会发现它们更易于使用。这是一个工作示例:
from plotly import graph_objs as go
import ipywidgets as w
from IPython.display import display
import pandas as pd
df = pd.DataFrame()
df['category'] = ['G1', 'G1', 'G1', 'G1','G1', 'G1','G1', 'G2', 'G2', 'G2', 'G2', 'G2', 'G2', 'G2']
df['date'] = ['2012-04-01', '2012-04-05', '2012-04-09', '2012-04-11', '2012-04-16', '2012-04-23', '2012-04-30',
'2012-04-01', '2012-04-05', '2012-04-09', '2012-04-11', '2012-04-16', '2012-04-23', '2012-04-30']
df['col1'] = [54, 34, 65, 67, 23, 34, 54, 23, 67, 24, 64, 24, 45, 89]
df['col2'] = round(df['col1'] * 0.85)
x = 'date'
y1 = 'col1'
y2 = 'col2'
trace1 = {
'x': df[x],
'y': df[y1],
'type': 'scatter',
'mode': 'lines',
'name':'col 1',
'marker': {'color': 'blue'}
}
trace2={
'x': df[x],
'y': df[y2],
'type': 'scatter',
'mode': 'lines',
'name':'col 2',
'marker': {'color': 'yellow'}
}
data = [trace1, trace2]
# Create layout for the plot
layout=dict(
title='my plot',
xaxis=dict(
title='Date',
type='date',
tickformat='%Y-%m-%d',
ticklen=5,
titlefont=dict(
family='Old Standard TT, serif',
size=20,
color='black'
)
),
yaxis=dict(
title='values',
ticklen=5,
titlefont=dict(
family='Old Standard TT, serif',
size=20,
color='black'
)
)
)
# Here's the new part
fig = go.FigureWidget(data=data, layout=layout)
def update_fig(change):
aux_df = df[df.category.isin(change['new'])]
with fig.batch_update():
for trace, column in zip(fig.data, [y1, y2]):
trace.x = aux_df[x]
trace.y = aux_df[column]
drop = w.Dropdown(options=[
('All', ['G1', 'G2']),
('G1', ['G1']),
('G2', ['G2']),
])
drop.observe(update_fig, names='value')
display(w.VBox([drop, fig]))
请注意,由于图形本身是一个ipython小部件,因此您现在甚至不需要导入offline
。 Plotly 3还实现了一种强制性的方式来编写我认为非常有用的代码,您可以在this post中阅读有关此功能和其他plotly 3功能的信息(可惜的是文档中并未涉及)。>
编辑
对于多个下拉列表,类似的东西应该起作用
def update_fig1(change):
aux_df = df[df.category == change['new']]
aux_df = aux_df[aux_df.category1 == drop2.value]
with fig.batch_update():
for trace, column in zip(fig.data, [y1, y2]):
trace.x = aux_df[x]
trace.y = aux_df[column]
def update_fig2(change):
aux_df = df[df.category1 == change['new']]
aux_df = aux_df[aux_df.category == drop1.value]
with fig.batch_update():
for trace, column in zip(fig.data, [y1, y2]):
trace.x = aux_df[x]
trace.y = aux_df[column]
drop1 = w.Dropdown(options=df.category.unique())
drop2 = w.Dropdown(options=df.category1.unique())
drop1.observe(update_fig1, names='value')
drop2.observe(update_fig2, names='value')
display(w.VBox([w.HBox([drop1, drop2]), fig]))