Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib histogram from numpy histogram output [duplicate]

I have run numpy.histogram() on a bunch of subsets of a larger datasets. I want to separate the calculations from the graphical output, so I would prefer not to call matplotlib.pyplot.hist() on the data itself.

In principle, both of these functions take the same inputs: the raw data itself, before binning. The numpy version just returns the nbin+1 bin edges and nbin frequencies, whereas the matplotlib version goes on to make the plot itself.

So is there an easy way to generate the histograms from the numpy.histogram() output itself, without redoing the calculations (and having to save the inputs)?

To be clear, the numpy.histogram() output is a list of nbin+1 bin edges of nbin bins; there is no matplotlib routine which takes those as input.

like image 332
Andrew Jaffe Avatar asked May 16 '17 13:05

Andrew Jaffe


2 Answers

You can plot the output of numpy.histogram using plt.bar.

import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)

a = np.random.rayleigh(scale=3,size=100)
bins = np.arange(10)

frq, edges = np.histogram(a, bins)

fig, ax = plt.subplots()
ax.bar(edges[:-1], frq, width=np.diff(edges), edgecolor="black", align="edge")

plt.show()

enter image description here

like image 154
ImportanceOfBeingErnest Avatar answered Sep 18 '22 18:09

ImportanceOfBeingErnest


New in matplotlib 3.4.0

It's no longer necessary to manually reconstruct a bar chart, as there's now a built-in method:

Use the new plt.stairs method for the common case where you know the values and edges of the steps, for instance when plotting the output of np.histogram.

Note that stairs are plotted as lines by default, so use fill=True for a solid histogram:

a = np.random.RandomState(1).rayleigh(3, size=100)

counts, edges = np.histogram(a, bins=range(10))
plt.stairs(counts, edges, fill=True)

If you want a more conventional "bar" aesthetic, combine with plt.vlines:

plt.stairs(counts, edges, fill=True)
plt.vlines(edges, 0, counts.max(), colors='w')

If you don't need the counts and edges, just unpack np.histogram directly into plt.stairs:

plt.stairs(*np.histogram(a), fill=True)

And as usual, there is an ax.stairs counterpart:

fig, ax = plt.subplots()
ax.stairs(*np.histogram(a), fill=True)
like image 32
tdy Avatar answered Sep 19 '22 18:09

tdy