Multiple related plots often need to share one figure so patterns can be compared without switching between separate image files. In Matplotlib, subplots are individual Axes inside one Figure, and each Axes can hold its own chart type, title, labels, and scale.
plt.subplots() creates the Figure and a grid of Axes in one call. Adding squeeze=False keeps the returned Axes object as a two-dimensional array, which makes row and column indexing predictable when the grid changes.
The saved PNG contains four support metrics in a 2×2 grid. layout=“constrained” lets Matplotlib reserve room for titles and labels, while sharex=True keeps the month axis aligned across panels.
from pathlib import Path import matplotlib.pyplot as plt months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"] created = [34, 38, 41, 46, 44, 49] resolved = [30, 35, 39, 42, 45, 47] escalated = [6, 5, 8, 7, 6, 4] satisfaction = [82, 84, 83, 86, 88, 90] fig, axs = plt.subplots( 2, 2, figsize=(8.8, 5.6), sharex=True, squeeze=False, layout="constrained", ) fig.suptitle("Support queue dashboard") axs[0, 0].plot(months, created, marker="o", color="tab:blue") axs[0, 0].set_title("Tickets created") axs[0, 0].set_ylabel("Tickets") axs[0, 1].bar(months, resolved, color="tab:green") axs[0, 1].set_title("Tickets resolved") axs[0, 1].set_ylabel("Tickets") axs[1, 0].plot(months, escalated, marker="s", color="tab:red") axs[1, 0].set_title("Escalations") axs[1, 0].set_xlabel("Month") axs[1, 0].set_ylabel("Tickets") axs[1, 1].plot(months, satisfaction, marker="^", color="tab:purple") axs[1, 1].set_title("Satisfaction score") axs[1, 1].set_xlabel("Month") axs[1, 1].set_ylabel("Score") axs[1, 1].set_ylim(75, 95) for ax in axs.flat: ax.grid(True, axis="y", alpha=0.25) output = Path("support-subplots.png") fig.savefig(output, dpi=160) plt.close(fig) titles = ", ".join(ax.get_title() for ax in axs.flat) shared_x = axs[0, 0].get_shared_x_axes().joined(axs[0, 0], axs[1, 1]) print(f"axes grid: {axs.shape[0]} rows x {axs.shape[1]} columns") print(f"axes titles: {titles}") print(f"shared x-axis: {shared_x}") print(f"saved: {output}") print(f"bytes: {output.stat().st_size}")
plt.subplots(2, 2, …) returns a Figure and a 2D array of Axes because squeeze=False keeps the array shape fixed.
$ python create_subplots.py axes grid: 2 rows x 2 columns axes titles: Tickets created, Tickets resolved, Escalations, Satisfaction score shared x-axis: True saved: support-subplots.png bytes: 99405
The byte count can change with Matplotlib, font, backend, or DPI differences. The expected grid, titles, shared axis state, and nonzero file size confirm that the script created the subplot figure.
The image should show two rows and two columns, one title per panel, shared month labels along the bottom row, and separate y-axis labels for the metrics.
months = ["Q1", "Q2", "Q3", "Q4"] created = [120, 135, 128, 144] resolved = [118, 130, 132, 140] escalated = [14, 12, 10, 9] satisfaction = [81, 84, 87, 89]
Each plotted series must align with the x-axis sequence. If one panel uses a different x-axis, remove sharex=True or create that panel with a separate layout.
$ rm create_subplots.py support-subplots.png