Plotly: How to display individual value on histogram?

Viewed 5450

I am trying to make dynamic plots with plotly. I want to plot a count of data that have been aggregated (using groupby). I want to facet the plot by color (and maybe even by column). The problem is that I want the value count to be displayed on each bar. With histogram, I get smooth bars but I can't find how to display the count: enter image description here

With a bar plot I can display the count but I don't get smooth bar and the count does not appear for the whole bar but for each case composing that bar enter image description here

Here is my code for the barplot

val = pd.DataFrame(data2.groupby(["program", "gender"])["experience"].value_counts())
px.bar(x=val.index.get_level_values(0), y=val, color=val.index.get_level_values(1), barmode="group", text=val)

It's basically the same for the histogram.

Thank you for your help!

2 Answers

px.histogram does not seem to have a text attribute. So if you're willing to do any binning before producing your plot, I would use px.Bar. Normally, you apply text to your barplot using px.Bar(... text = <something>). But this gives the results you've described with text for all subcategories of your data. But since we know that px.Bar adds data and annotations in the order that the source is organized, we can simply update text to the last subcategory applied using fig.data[-1].text = sums. The only challenge that remains is some data munging to retrieve the correct sums.

Plot:

enter image description here

Complete code with data example:

import plotly.graph_objects as go
import plotly.express as px
import pandas as pd

# data
df = pd.DataFrame({'x':['a', 'b', 'c', 'd'],
                       'y1':[1, 4, 9, 16],
                       'y2':[1, 4, 9, 16],
                       'y3':[6, 8, 4.5, 8]})
df = df.set_index('x')

# calculations
# column sums for transposed dataframe
sums= []
for col in df.T:
    sums.append(df.T[col].sum())

# change dataframe format from wide to long for input to plotly express
df = df.reset_index()
df = pd.melt(df, id_vars = ['x'], value_vars = df.columns[1:])

fig = px.bar(df, x='x', y='value', color='variable')
fig.data[-1].text = sums

fig.update_traces(textposition='inside')
fig.show()

If your first graph is with graph object librairy you can try:

# Use textposition='auto' for direct text
fig=go.Figure(data[go.Bar(x=val.index.get_level_values(0),
 y=val, color=val.index.get_level_values(1), 
 barmode="group", text=val, textposition='auto',
    )])
Related