Plotly 条形图 - 使用下拉菜单选择一列,然后让条形图按列排序?

问题描述 投票:0回答:1

我想要达到的目标:

我想在 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 的了解还不够,无法真正弄清楚我哪里出错了,但是例如,如果我从下拉列表中选择“黄金”列,购物车将更新为:

我如何实施所需的更改?我认为这不会太困难,但我在这里,几个小时后试图弄清楚这一点。任何帮助表示赞赏!

python jupyter-notebook plotly visualization plotly-python
1个回答
0
投票

我认为原因是个别图表是按名称创建的。因此,图表是使用按目标列的降序排序的数据框创建的,并设置为仅显示第一个。此外,对于性别颜色编码,我需要一个颜色列表,因此我通过引用数据框中的字典来创建一个颜色列表。 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)

© www.soinside.com 2019 - 2024. All rights reserved.