我想在一个复杂的线条图中创建一个下拉菜单,比如in this post,但有几行。
让我们看一个 Dataframe 示例:
import pandas as pd
df = pd.DataFrame({"Date": ["2022-10-01","2022-10-02","2022-10-03","2022-10-01","2022-10-02","2022-10-03","2022-10-01","2022-10-02","2022-10-03","2022-10-01","2022-10-02","2022-10-03"],
"Animal" :["Cat","Cat","Cat","Cat","Cat","Cat","Dog","Dog","Dog","Dog","Dog","Dog"],
"Category":["Small","Small","Small","Big","Big","Big","Small","Small","Small","Big","Big","Big"],
"Quantity":[2,4,3,5,1,2,6,5,6,4,2,1]})
df["Date"] = df["Date"].astype('datetime64')
我想用Date
在x轴上,Quantity
的y轴上,每个Animal
有一条曲线,每个m2n3o1p都有一个滤波器。我尝试了下面的函数,但结果不好,因为线在晃动。你能知道我的错误在哪里吗?
import plotly.graph_objects as go
def plot_line_go_graph(df,col_x,col_y,col_color = None,col_filter = None,add_points = False) :
df_graph = df.copy()
if add_points :
param_mode='lines+markers'
param_name='lines+markers'
else :
param_mode='lines'
param_name='lines'
fig = go.Figure()
if col_filter is None :
if col_color is None :
fig.add_trace(go.Scatter(x=df_graph[col_x], y=df_graph[col_y],mode=param_mode,name=param_name))
else :
for c in df_graph[col_color].unique() :
fig.add_trace(go.Scatter(x=df_graph[df_graph[col_color]==c][col_x], y=df_graph[df_graph[col_color]==c][col_y],mode=param_mode,name=c))
else :
df_graph[col_filter] = df_graph[col_filter].fillna("NaN")
if col_color is None :
fig.add_trace(go.Scatter(x=df_graph[col_x], y=df_graph[col_y],mode=param_mode,name=param_name,visible = True))
else :
for c in df_graph[col_color].unique() :
fig.add_trace(go.Scatter(x=df_graph[df_graph[col_color]==c][col_x], y=df_graph[df_graph[col_color]==c][col_y],mode=param_mode,name=c,visible = True))
updatemenu = []
buttons = []
# button with one option for each dataframe
buttons.append(dict(method='restyle',
label="All",
visible=True,
args=[{'y':[df_graph[col_y]],
'x':[df_graph[col_x]],
'type':'scatter'}, [0]],
)
)
for f in df_graph[col_filter].unique():
buttons.append(dict(method='restyle',
label=f,
visible=True,
args=[{'y':[df_graph[df_graph[col_filter]==f][col_y]],
'x':[df_graph[df_graph[col_filter]==f][col_x]],
'type':'scatter'}, [0]],
)
)
# some adjustments to the updatemenus
updatemenu = []
your_menu = dict()
updatemenu.append(your_menu)
updatemenu[0]['buttons'] = buttons
updatemenu[0]['direction'] = 'down'
updatemenu[0]['showactive'] = True
# add dropdown menus to the figure
fig.update_layout(updatemenus=updatemenu)
if col_color is None :
fig.update_layout(showlegend=False)
fig.update_layout({
'plot_bgcolor': 'rgba(0,0,0,0)',
'paper_bgcolor': 'rgba(0,0,0,0)',
},
hoverlabel=dict(
#bgcolor="white",
font_size=12,
#font_family="Rockwell"
),
hovermode = "x"
)
fig.update_xaxes(showspikes=True, spikecolor = 'black', showline=True, linewidth=1,linecolor='black', ticks = "outside", tickwidth = 1, tickcolor = 'black',ticklen = 5)
fig.update_yaxes(showspikes=True, spikecolor = 'black', showline=True, linewidth=1,linecolor='black', ticks = "outside", tickwidth = 1, tickcolor = 'black',ticklen = 5)
fig.show()
plot_line_go_graph(df,"Date","Quantity",col_color = "Animal", col_filter = "Category",add_points = False)
小时
1条答案
按热度按时间ohtdti5x1#
我认为这里有一些问题。第一个问题是,当您绘制由
"Category"
(例如"Big"
或"Small"
)过滤的数据时,您将绘制重复日期的数据,这就是导致线在时间上倒退的原因,这使得绘制很难解释。相反,您可以通过对
col_color, col_filter
执行groupby来添加记录道—在您的示例中,如果按["Animal", "Category"]
分组,则应该有四个唯一的组,因此有四个记录道。然后,我认为您可以重新设计按钮,根据跟踪的名称是否包含特定的col_filter来切换每个跟踪的可见性。例如,如果您的记录道被称为
("Cat","Big"),("Cat,"Small"),("Dog","Big"),("Dog","Small")
,当您单击按钮“Big”时,它会将四条记录道的可见性切换为m1n 6o1p。而"All"
按钮会将所有记录道的可视性设置为m1 n8o1p。小时