HOWTO · Matplotlib
How to Manually Set the Size of the Bins in Matplotlib Histogram
Set Matplotlib histogram bin widths by passing explicit or generated boundaries to the bins argument of plt.hist().
On this page
To control the widths in a one-dimensional Matplotlib histogram, pass the data and a sequence of boundaries to plt.hist(..., bins=...). Each adjacent pair of boundary values defines one interval, so a sequence can create either equal-width or unequal-width bins. hist2d() is for two-dimensional histograms; the examples here use plt.hist().
Bin Boundaries as a Parameter to hist() Function
Use a boundary sequence when you want to choose where intervals begin and end. For example, [0, 10, 20, 30, 40, 50, 60, 80, 100] creates eight bins: the first six have width 10, and the last two have width 20. The number of bins is one less than the number of boundaries. Values outside the first and last boundaries are not counted in the histogram, so choose a range that covers the observations you want to include.
When all bins should have the same width, generate regularly spaced boundaries with np.arange. The example below compares chosen boundaries with equal-width boundaries for the same values. Since np.arange(start, stop, step) includes start and excludes stop, the stop value must extend beyond the largest observation to cover it.
import matplotlib.pyplot as plt
import numpy as np
values = np.array([3, 8, 12, 18, 24, 31, 37, 43, 52, 61, 74, 88, 96])
width = 10
explicit_edges = [0, 10, 20, 30, 40, 50, 60, 80, 100]
equal_edges = np.arange(0, 101, width)
fig, axes = plt.subplots(1, 2, figsize=(10, 4))
axes[0].hist(values, bins=explicit_edges)
axes[0].set_title("Chosen boundaries")
axes[1].hist(values, bins=equal_edges)
axes[1].set_title("Equal-width bins")
for axis in axes:
axis.set_xlabel("Value")
axis.set_ylabel("Count")
fig.tight_layout()
plt.show()
For data-driven equal-width bins, a convenient stop is max(values) + width. Because np.arange excludes its stop, that stop is not itself an edge. With these values, the stop is 106 and the last generated edge is 100, which still covers the maximum observation of 96. If the range or width changes, calculate the boundaries from the current data rather than keeping a fixed list.
Compute the Number of Bins From Desired Width
If the data range is only known when the program runs, derive the first and last boundaries from the observations. This example rounds the first boundary down to a multiple of the requested width and extends the final boundary to a multiple at or above the maximum. It assumes a nonempty numeric dataset and a positive width. The outer bins can extend beyond the data range; the spacing between every adjacent pair remains the requested width.
import matplotlib.pyplot as plt
import numpy as np
values = np.array([3, 8, 12, 18, 24, 31, 37, 43, 52, 61, 74, 88, 96])
width = 10.0
first_edge = np.floor(values.min() / width) * width
last_edge = np.ceil(values.max() / width) * width
edges = np.arange(first_edge, last_edge + width, width)
plt.hist(values, bins=edges)
plt.xlabel("Value")
plt.ylabel("Count")
plt.title(f"Histogram with bin width {width:g}")
plt.show()
Here, the minimum is 3 and the maximum is 96, so the generated boundaries run from 0 through 100 in steps of 10. The observations are counted in those intervals, and the plotted histogram uses the requested width. For a different width, update width; the same calculation generates the corresponding boundary sequence. If the data are empty or the width is not positive, handle that input before computing the boundaries.