Adding percentage of count to a stacked bar chart in plotly
Asked Answered
C

3

5

Given the following chart created in plotly. enter image description here

I want to add the percentage values of each count for M and F categories inside each block.

The code used to generate this plot.

arr = np.array([
        ['Dog', 'M'], ['Dog', 'M'], ['Dog', 'F'], ['Dog', 'F'],
        ['Cat', 'F'], ['Cat', 'F'], ['Cat', 'F'], ['Cat', 'M'],
        ['Fox', 'M'], ['Fox', 'M'], ['Fox', 'M'], ['Fox', 'F'],
        ['Dog', 'F'], ['Dog', 'F'], ['Cat', 'F'], ['Dog', 'M']
    ])

df = pd.DataFrame(arr, columns=['A', 'G'])

fig = px.histogram(df, x="A", color='G', barmode="stack")
fig.update_layout(height=400, width=800)

fig.show()
Census answered 10/12, 2020 at 10:50 Comment(0)
P
16

As far as I know histograms in Plotly don't have a text attribute. But you could generate the bar chart yourself and then add the percentage via the text attribute.

import numpy as np
import pandas as pd
import plotly.express as px

arr = np.array([
        ['Dog', 'M'], ['Dog', 'M'], ['Dog', 'F'], ['Dog', 'F'],
        ['Cat', 'F'], ['Cat', 'F'], ['Cat', 'F'], ['Cat', 'M'],
        ['Fox', 'M'], ['Fox', 'M'], ['Fox', 'M'], ['Fox', 'F'],
        ['Dog', 'F'], ['Dog', 'F'], ['Cat', 'F'], ['Dog', 'M']
    ])

df = pd.DataFrame(arr, columns=['A', 'G'])

df_g = df.groupby(['A', 'G']).size().reset_index()
df_g['percentage'] = df.groupby(['A', 'G']).size().groupby(level=0).apply(lambda x: 100 * x / float(x.sum())).values
df_g.columns = ['A', 'G', 'Counts', 'Percentage']

px.bar(df_g, x='A', y=['Counts'], color='G', text=df_g['Percentage'].apply(lambda x: '{0:1.2f}%'.format(x)))

enter image description here

Pantin answered 10/12, 2020 at 21:11 Comment(1)
The code looks good, just that for me the last line had to be changed to: px.bar(df_g, x='A', y='Counts', color='G', text=df_g['Percentage'].apply(lambda x: '{0:1.2f}%'.format(x)))Truelove
C
8

Note that you can now specify plotly barnorm and text_auto arguments to achieve this. Have a look at your example:

# Libraries
import numpy as np
import pandas as pd
import plotly.express as px

# Data
arr = np.array([
    ['Dog', 'M'], ['Dog', 'M'], ['Dog', 'F'], ['Dog', 'F'],
    ['Cat', 'F'], ['Cat', 'F'], ['Cat', 'F'], ['Cat', 'M'],
    ['Fox', 'M'], ['Fox', 'M'], ['Fox', 'M'], ['Fox', 'F'],
    ['Dog', 'F'], ['Dog', 'F'], ['Cat', 'F'], ['Dog', 'M']
])

df = pd.DataFrame(arr, columns=['A', 'G'])

#Plotly Code
fig = go.Figure()

fig = px.histogram (  df,
                      x="A",
                      color="G",
                      barnorm = "percent",
                      text_auto= True,
                      color_discrete_sequence=["mediumvioletred", "seagreen"],
                ) \
        .update_layout (

                    title={
                            "text": "Percent :A - G",
                            "x": 0.5
                          },

                    yaxis_title="Percent"
                ) \
        .update_xaxes(categoryorder='total descending')

fig.show()

In general it should be the prefered solution over calculating the percentages yourself. Here the output:

Plot Image

Calculating answered 2/1, 2022 at 10:38 Comment(4)
TypeError: histogram() got an unexpected keyword argument 'text_auto'Tarsia
Make sure you have most recent update for your plotly installation.Calculating
Upgrading from plotly 5.4 to 5.6 allowed me to use 'text_auto'Carlina
That should be the accepted answer as in March 2022.Pantin
G
0

You can also use the text argument in px.bar() to specify custom text labels for each bar. If you want to display the values as percentages, you can use the str.format() method to format the text labels.

topCom = df["Make"].value_counts().sort_values(ascending=False).head(10)
px.bar(x= topCom.index ,y= topCom/742*100,
text=[f"{value:.2f}%" for value in topCom/742*100],
color_discrete_sequence=['#4C4C6D'])
Gorrono answered 28/9, 2023 at 5:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.