Search code examples
pythonplotlyplotly-python

How to show percentage alongside of values in plotly bar charts?


I want to plot percentage alongside values of each bar chart, something like that, or in one line with values (value + percentage)

enter image description here

I can achieve it with a pie chart with the help of this line: fig.update_traces(hoverinfo='label+percent', textinfo='value+percent', textposition='outside'). But struggling to do it with a bar chart. Can anyone help me to to it in fig.update_traces or by editing fig.add_trace(go.Bar()

enter image description here

Example of code I am using for plotting:

data = {'bin': [1, 2, 1, 2, 3], 'id': [1, 2, 3, 3, 3], 'type': [0, 1, 1, 1, 0]}
df = pd.DataFrame(data=data)
df1 = df[df['type']==0]
df2 = df[df['type']==1]


# dict for the dataframes and their names
dfs = {"df1" : df1, "df2" : df2}

# plot the data
temp=dict(layout=go.Layout(font=dict(family="Franklin Gothic", size=12), height=1000, width=1000))
fig = go.Figure()

for i in dfs:
        tmp = dfs[i]
        print(i, ': ', tmp.groupby(['bin'])['id'].nunique().keys()) 
        X = tmp.groupby(['bin'])['id'].nunique().keys()
        Y = tmp.groupby(['bin'])['id'].nunique().tolist()
        fig = fig.add_trace(go.Bar(x = X,
                                   y = Y, 
                                   name = i))

fig.update_traces(texttemplate='%{y}', textposition='outside')
fig.show()

Solution

  • Here's an example keeping your code structure. It uses the argument text in go.Bar(...). Here you can use HTML tags to properly format the text.

    data = {'bin': [1, 2, 1, 2, 3], 'id': [1, 2, 3, 3, 3], 'type': [0, 1, 1, 1, 0]}
    df = pd.DataFrame(data=data)
    df1 = df[df['type']==0]
    df2 = df[df['type']==1]
    
    
    # dict for the dataframes and their names
    dfs = {"df1" : df1, "df2" : df2}
    
    # plot the data
    temp=dict(layout=go.Layout(font=dict(family="Franklin Gothic", size=12), height=1000, width=1000))
    fig = go.Figure()
    
    for i in dfs:
            tmp = dfs[i]
            print(i, ': ', tmp.groupby(['bin'])['id'].nunique().keys()) 
            X = tmp.groupby(['bin'])['id'].nunique().keys()
            Y = tmp.groupby(['bin'])['id'].nunique().tolist()
            Y_text = [str(i) + f'<br>({i}%)</br>' for i in Y]
            
            fig = fig.add_trace(go.Bar(x = X,
                                       y = Y,
                                       text = Y_text, 
                                       name = i))
    
    fig.update_traces(textposition='outside')
    fig.show()