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
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.
$ 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.
The tallest bar should cover the 5 to 10 hour bin, and the x-axis should show the same edges passed to ax.hist().
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.
$ rm create_histogram.py ticket-response-histogram.png