我想在 plotly python 中有一个带有单个下拉菜单的水平条形图。下拉菜单选项是给定数据框的所有列名称。我希望条形图根据下拉列表中选择的任何列自行排序。这样的事情可能吗?
我的情节代码如下所示:
def gen_bar(df, title, sub, col='Podium'):
"""
Displays an interactive plotly graph using the given column and dataframe.
df: dataframe containing relevant data
col: data to be displayed along x-axis
title: title (and subtitle) for given visualization
"""
# Top 10 men and women
comb = df.sort_values(col, ascending=False)[:20]
# Define colors
color_discrete_map = {"M": "#10baee", "F": "#ff007e"}
# Define plot
fig=go.Figure()
for r in comb['Name'].unique():
dfp = comb[comb['Name'] == r]
g = dfp['Gender'].values[0]
fig.add_traces(
go.Bar(x=dfp[col],
y=dfp['Name'],
customdata=[col],
name='',
marker_color=color_discrete_map[g],
orientation='h',
hovertemplate="<b>%{y}</b><br>%{customdata}: %{x}"
))
# Define buttons for dropdown
col_opts = list(df.columns[4:])
buttons_opts = []
for i, opt in enumerate(col_opts):
args = [False] * len(col_opts)
args[i] = True
buttons_opts.append(
dict(
method='restyle',
label=opt,
args=[{
'visible': args, #this is the key line!
'title': opt,
'showlegend': False
}]
)
)
# Styling
title = f"{title}<br><sup>{sub}"
fig.update_layout(
updatemenus = [go.layout.Updatemenu(
active=col_opts.index(col),
buttons=buttons_opts,
x=1.12,
xanchor='right',
y=1.1,
yanchor='top'
)],
yaxis={
'autorange': "reversed",
'showline': True,
'linecolor': 'black',
'title': None
},
title=dict(text=title, font=dict(size=30)),
showlegend=False,
width=1000,
height=600,
plot_bgcolor='#f0f0f0',
paper_bgcolor='#f0f0f0',
xaxis_title=None,
margin=dict(l=85, r=85, t=95, b=45)
)
fig.show(config=config)
title = "Top 20 Climbers in IFSC"
sub = f"Based on total number of given value"
gen_bar(all_boulder_podiums, title, sub, 'Podium')
虽然下拉菜单有效,但图表没有正确更新。我对 plotly 的了解还不够,无法真正弄清楚我哪里出错了,但是例如,如果我从下拉列表中选择“黄金”列,购物车将更新为:
我如何实施所需的更改?我认为这不会太困难,但我在这里,几个小时后试图弄清楚这一点。任何帮助表示赞赏!
我认为原因是个别图表是按名称创建的。因此,图表是使用按目标列的降序排序的数据框创建的,并设置为仅显示第一个。此外,对于性别颜色编码,我需要一个颜色列表,因此我通过引用数据框中的字典来创建一个颜色列表。 Active 按钮决定了作为初始显示要显示的图的编号,并设置为您要显示的第一个图(默认值为 0)。
import plotly.graph_objects as go
def gen_bar(df, title, sub):
"""
Displays an interactive plotly graph using the given column and dataframe.
df: dataframe containing relevant data
col: data to be displayed along x-axis
title: title (and subtitle) for given visualization
"""
# Top 10 men and women
#comb = df.sort_values(col, ascending=False)[:20]
comb = df[:20]
# Define colors
color_discrete_map = {"M": "#10baee", "F": "#ff007e"}
# Define plot
fig=go.Figure()
for k,r in enumerate(df.columns[4:]):
#dfp = comb[comb['Name'] == r]
dfp = comb.sort_values(r, ascending=False)
g = dfp['Gender'].values
print(g)
colors = [color_discrete_map[x] for x in g]
fig.add_traces(
go.Bar(x=dfp[r],
y=dfp['Name'],
customdata=dfp[r].values,
name='',
marker_color=colors,#color_discrete_map[g],
orientation='h',
hovertemplate="<b>%{y}</b><br>%{customdata}: %{x}",
visible=True if k == 0 else False
))
# Define buttons for dropdown
col_opts = list(df.columns[4:])
buttons_opts = []
for i, opt in enumerate(col_opts):
args = [False] * len(col_opts)
args[i] = True
buttons_opts.append(
dict(
method='restyle',
label=opt,
args=[{
'visible': args, #this is the key line!
'title': opt,
'showlegend': False
}]
)
)
# Styling
title = f"{title}<br><sup>{sub}"
fig.update_layout(
updatemenus = [go.layout.Updatemenu(
active=0,#col_opts.index(col),
buttons=buttons_opts,
x=1.12,
xanchor='right',
y=1.1,
yanchor='top'
)],
yaxis={
'autorange': "reversed",
'showline': True,
'linecolor': 'black',
'title': None
},
title=dict(text=title, font=dict(size=30)),
showlegend=False,
width=1000,
height=600,
plot_bgcolor='#f0f0f0',
paper_bgcolor='#f0f0f0',
xaxis_title=None,
margin=dict(l=85, r=85, t=95, b=45)
)
# print(fig.data)
fig.show()#config=config
title = "Top 20 Climbers in IFSC"
sub = f"Based on total number of given value"
gen_bar(all_boulder_podiums, title, sub)