Creating a histogram with "segments"

I am trying to create a histogram in Dash with data that looks like this:

Month      |  Role        |    Quantity
-----------------------------------------------
January       Engineer      10
January       Lawyer        2
January       Doctor        2
February      Engineer      9
February      Lawyer        4
February      Doctor        1
March         Engineer      6
March         Lawyer        3
March         Doctor        7

I would like the histogram to have the Quantity of total employees on the y-axis and the months on the x-axis.

Each bar should show the total number of employees for each month. At the same time, each bar show be composed of “segments” representing each type of employee for that month.

Could you please help out with this?

I’ve studied some examples about histograms, but don’t know how to divide each bar by segments corresponding to each type of worker.

Thank you.

Welcome to the community, @Ricardo.

Are you referring to something like this?

import pandas as pd
import plotly.express as px

df = pd.DataFrame({'month': ['January', 'February', 'March'], 'engineer': [10,9,6], 'doctor': [2,1,7], 'lawyer': [2,4,3]})
fig = px.bar(df, x='month', y=df.columns[1:], barmode='stack')
fig.show()

newplot

This is a bar chart with the mode set to stack

Instead of stack there are other options like group. Applying this to your example, you could calculate the sum separately and add it as bar to the chart:

import pandas as pd
import plotly.express as px

df = pd.DataFrame({'month': ['January', 'February', 'March'], 'engineer': [10,9,6], 'doctor': [2,1,7], 'lawyer': [2,4,3]})
df['total'] = df[df.columns[1:]].sum(axis = 1)

fig = px.bar(df, x='month', y=df.columns[1:], barmode='group')
fig.show()

newplot (2)

1 Like

@AIMPED that’s exactly it, thank you so much!

Now I have to see how to convert the real data, which is read from an XLS file, to make it work with your code. But I think I can work that out.

Thank you once again!

1 Like

HI @Ricardo,

I think the pandas pivot table might help. Try this:

import pandas as pd
import plotly.express as px

df=pd.read_csv('csv.txt', delimiter=',', index_col=False)
pivot = df.pivot_table('Quantity', ['Month'], 'Role')

fig = px.bar(pivot, x=pivot.index, y=pivot.columns, barmode='stack')
fig.show()

csv.txt:

Month,Role,Quantity
January,Engineer,10
January,Lawyer,2
January,Doctor,2
February,Engineer,9
February,Lawyer,4
February,Doctor,1
March,Engineer,6
March,Lawyer,3
March,Doctor,7
1 Like

That’s a much better approach than what I came up with, thanks a ton!

This is how the code is looking:

    fig = px.bar(df, x='month', y='fte',
                 barmode='stack',
                 # showlegend=True,
                 labels={"x": "Months before SOP", "y": "FTE"})

    fig.update_layout(showlegend=True, legend_title_text="Roles legend")

Now I have a few (minor?) issues with my graph:

  1. All the “stacks” in all the columns appear with the same color, while as in your example each role has its own color.
  2. The legend is not showing up in my graph. And also, I’d like to display it in a particular div of my HTML layout (Besides the Roles header in the right hand sidebar). Is this possible?
  3. The titles for each axis are the same as the column name in the XLS file I’m reading from. I’m trying to change them to something more user friendly using labels={"x": "Months before SOP", "y": "FTE"}, but not succeeding.
  4. Currently when hovering over each segment, a “tool tip” appears displaying information about the month and the quantity of people with that role (eg. Lawyer). But it doesn’t show the role itself (“Lawyer”), how could I add this to the tool tip?

This is how it looks:

I’m not sure if this thread is the best place to tackle them or I should rather open a new thread?

That is, because you are using one column of your df. Try using the colorparameter and use the different roles as argument (as a list).
The legend should show up automatically.

That’s not possible, the legend can be showed within the figure only

1 Like

Thank you @AIMPED!

That was really usefull!

Appreciate it a lot :slight_smile:

1 Like