Let's say that I have a value that I've measured every day for the past 90 days. I would like to plot a histogram of the values, but I want to make it easy for the viewer to see where the measurements have accumulated over certain non-overlapping subsets of the past 90 days. I want to do this by "subdividing" each bar of the histogram into chunks. One chunk for the earliest observations, one for more recent, one for the most recent.
This sounds like a job for df.plot(kind='bar', stacked=True)
but I'm having trouble getting the details right.
Here's what I have so far:
import numpy as np
import pandas as pd
import seaborn as sbn
np.random.seed(0)
data = pd.DataFrame({'values': np.random.randn(90)})
data['bin'] = pd.cut(data['values'], 15, labels=False)
forhist = pd.DataFrame({'first70': data[:70].groupby('bin').count()['bin'],
'next15': data[70:85].groupby('bin').count()['bin'],
'last5': data[85:].groupby('bin').count()['bin']})
forhist.plot(kind='bar', stacked=True)
And that gives me:
This graph has some shortcomings:
last5
should be on top and next15
in the middle. I.e. they should be stacked in the order of the columns in forhist
. data['values'].hist()
. My "second choice" would be to have the x-axis labelled with the "bin names" that I would get if I did pd.cut(data['values'], 15)
. In my code, I used labels=False
because if I didn't do that, it would have used the bin edge labels (as strings) as the bar labels, and it would have put these in alphabetical order, making the graph basically useless.What's the best way to approach this? I feel like I'm using very clumsy functions so far.
Ok, here's one way to attack it, using features from the matplotlib
hist
function itself:
fig, ax = plt.subplots(1, 1, figsize=(9, 5))
ax.hist([data.ix[low:high, 'values'] for low, high in [(0, 70), (70, 85), (85, 90)]],
bins=15,
stacked=True,
rwidth=1.0,
label=['first70', 'next15', 'last5'])
ax.legend()
Which gives:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With