Numeric measurements often need a distribution view before a mean or total says enough. A histogram groups continuous values into bins, making clusters, skew, and sparse ranges visible in one Matplotlib figure.
Use Axes.hist() when the data is still a list or array of observations. It calculates the bin counts and draws the bars on the Axes; explicit bin edges keep the grouping stable between runs and reports.
The script saves a PNG and prints the returned bin count, bin totals, labels, filename, and byte size. Replace the practice values with the real numeric series after the bin widths and labels match the question being answered.
Related: How to create a box plot in Matplotlib
Related: How to create a bar chart in Matplotlib
Related: How to set axis labels in Matplotlib
Steps to create a Matplotlib histogram:
- Save the histogram script as create_histogram.py.
- create_histogram.py
from pathlib import Path import matplotlib.pyplot as plt response_hours = [ 4, 5, 5, 6, 7, 7, 8, 9, 9, 9, 10, 11, 12, 12, 13, 14, 15, 16, 18, 20, 22, 25, 28, 31, ] bin_edges = [0, 5, 10, 15, 20, 25, 30, 35] fig, ax = plt.subplots(figsize=(7, 4.5), layout="constrained") counts, edges, patches = ax.hist( response_hours, bins=bin_edges, color="tab:blue", edgecolor="white", ) ax.set_title("Support ticket response times") ax.set_xlabel("Hours to first response") ax.set_ylabel("Ticket count") ax.set_xticks(bin_edges) ax.grid(axis="y", linestyle=":", alpha=0.5) output = Path("ticket-response-histogram.png") fig.savefig(output, dpi=160) plt.close(fig) print(f"bins: {len(edges) - 1}") print(f"counts: {[int(count) for count in counts]}") print(f"x label: {ax.get_xlabel()}") print(f"y label: {ax.get_ylabel()}") print(f"saved: {output}") print(f"bytes: {output.stat().st_size}")
ax.hist() returns the bin totals, bin edges, and bar artists. The explicit bin_edges list makes the intervals readable and keeps the saved chart consistent.
- Run the script from the Python environment that has Matplotlib installed.
$ python create_histogram.py bins: 7 counts: [1, 9, 6, 3, 2, 2, 1] x label: Hours to first response y label: Ticket count saved: ticket-response-histogram.png bytes: 30719
The byte count can vary by Matplotlib version, font, backend, and DPI. A nonzero byte count with the expected filename confirms that the image was written.
- Open ticket-response-histogram.png and confirm the rendered distribution.
The tallest bar should cover the 5 to 10 hour bin, and the x-axis should show the same edges passed to ax.hist().
- Replace response_hours and bin_edges with values for the real dataset.
response_hours = [3, 4, 6, 8, 11, 13, 21, 22] bin_edges = [0, 6, 12, 18, 24]
Use density=True and change the y-axis label to Density when comparing distribution shapes across datasets with different sample sizes.
- Remove the practice files when the histogram was only a test.
$ rm create_histogram.py ticket-response-histogram.png
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.