18

i am trying to create a stacked histogram of grouped values using this code:

titanic.groupby('Survived').Age.hist(stacked=True)

But I am getting this histogram without stacked bars.

enter image description here

How can i get the histogram's bar stacked without having to use matplotlib directly or iterating over groups?

Dataset used: https://www.udacity.com/api/nodes/5454512672/supplemental_media/titanic-datacsv/download

leokury
  • 429
  • 1
  • 4
  • 15

4 Answers4

23

Improve the answer, the best way could be:

titanic.pivot(columns='Survived').Age.plot(kind = 'hist', stacked=True)

enter image description here

HMD
  • 2,202
  • 6
  • 24
  • 37
Raymond W
  • 666
  • 5
  • 10
12

The best way that I found so far is to create a new dataframe with the groups:

pd.DataFrame({'Non-Survivors': titanic.groupby('Survived').get_group(0).Age,
              'Survivors':   titanic.groupby('Survived').get_group(1).Age})
            .plot.hist(stacked=True)

enter image description here

leokury
  • 429
  • 1
  • 4
  • 15
  • 6
    When grouping by columns with more values, this is probably easier: `pd.DataFrame({k: v for k, v in titanic.groupby('Survived').Age}).plot.hist(stacked=True)` – nnnmmm Mar 27 '18 at 12:17
  • 1
    Best solution for me here, in particular as `df.pivot` is a very specific operation that only works for categorical serie. – Joël Jul 12 '19 at 13:47
5

I defined a custom function that leverages np.histogram
Also note that the histogram groups are calculated within groups of 'Survived'

def hist(x):
    h, e = np.histogram(x.dropna(), range=(0, 80))
    e = e.astype(int)
    return pd.Series(h, zip(e[:-1], e[1:]))

kw = dict(stacked=True, width=1, rot=45)
titanic.groupby('Survived').Age.apply(hist).unstack(0).plot.bar(**kw)

enter image description here

piRSquared
  • 285,575
  • 57
  • 475
  • 624
4

This solution uses a bar plot instead of a histogram but I think it gives you what you are looking for.

titanic.groupby(['Survived', pd.cut(titanic['Age'], np.arange(0,100,10))])\
       .size()\
       .unstack(0)\
       .plot.bar(stacked=True)

enter image description here

Ted Petrou
  • 59,042
  • 19
  • 131
  • 136