How to re-use the return values of matplotlib.Axes.hist?

Viewed 312

Suppose I want to plot a histogram of the same data twice:

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(8,6))
ax1,ax2 = fig.subplots(nrows=2,ncols=1)
ax1.hist(foo)
ax2.hist(foo)
ax2.set_yscale("log")
ax2.set_xlabel("foo")
fig.show()

Note that I call Axes.hist twice, and it could be expensive. I wonder if there is an easy way to re-use the return value of the 1st call to make the second one cheap.

1 Answers

In the ax.hist docs, there is a related example of reusing np.histogram output:

The weights parameter can be used to draw a histogram of data that has already been binned by treating each bin as a single point with a weight equal to its count.

counts, bins = np.histogram(data)
plt.hist(bins[:-1], bins, weights=counts)

We can use the same approach with ax.hist since it also returns counts and bins (along with a bar container):

x = np.random.default_rng(123).integers(10, size=100)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 3))

counts, bins, bars = ax1.hist(x)          # original hist
ax2.hist(bins[:-1], bins, weights=counts) # rebuilt via weights params

rebuilt via weights param


Alternatively, reconstruct the original histogram using ax.bar and restyle the width/alignment to match ax.hist:

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 3))

counts, bins, bars = ax1.hist(x)                    # original hist
ax2.bar(bins[:-1], counts, width=1.0, align='edge') # rebuilt via ax.bar

rebuilt via ax.bar

Related