Create Panel Figure Layouts in Matplotlib with Gridspec | by Naveen Venkatesan | Towards Data Science

Publication figures typically require multiple plots placed into a panelled layout to tell a story. A simple drag-and-drop method to do this could be to individually create each plot, and then use either an image-editing program or even Powerpoint to arrange plots into a full figure and save as one image. The problem with this approach; however, is that size consistency between fonts, etc. is difficult if you have to keep editing the individual plots, resizing, and moving to fit into your figure layout. One way to ensure consistent formatting amongst all of the individual plots is to directly create the panelled figure in matplotlib and export as one image. Fortunately for us, there is a powerful tool called gridspec that we can use to let matplotlib do most of the work for us. Let’s start out by creating a blank figure with a size of 10 x 10 inches:
# Import Librariesimport matplotlib.pyplot as pltimport numpy as np# Create Blank Figurefig = plt.figure(figsize=(10, 10))
Let’s say that this is the layout that we want to ultimately produce from our script:
If we want to use gridspec to our advantage, we need to simplify our layout into a grid. So to design the layout, we can think of the above figure as a 4 x 4 grid, with Plot 3 taking up the two bottom squares. We can create this initial grid as follows:
# Create 4x4 Gridgs = fig.add_gridspec(nrows=2, ncols=2)
Now that we have our grid, we can create three axes objects corresponding to the three plots in the layout above. We can index our gridspec much like we would any two-dimensional array or list. Note that for ax3 we index gs[1, :], meaning that the axis object will span the second row and both of the columns.
# Create Three Axes Objectsax1 = fig.add_subplot(gs[0, 0])ax2 = fig.add_subplot(gs[0, 1])ax3 = fig.add_subplot(gs[1, :])
There it is! We have the basic layout we were trying to create initially. The current layout is using 4 equally-sized squares with the default amount of spacing between them. Say we wanted a bit more control of the layout — we can start with the horizontal and vertical gaps between the individual plot in the figure, we can pass hspace (height space) and wspace (width space) as arguments. These keyword arguments take in a float value corresponding to a fraction of the average axes height and width.
# Edit gridspec to change hspace and wspacegs = fig.add_gridspec(nrows=2, ncols=2, hspace=0.5, wspace=0.5)
As you can see, the plots are now farther spaced out because the space is being calculated as half of the average axis width and height. Now, say that we actually wanted Plot 1 to be twice the width of Plot 2, and Plot 3 to have half the height of Plot 1 and Plot 2. We can adjust this using the height_ratios and width_ratios keyword arguments. Both these arguments take a list of floats that describe the ratios of the axes heights and widths, respectively.
# Edit gridspec to change height_ratios and width_ratiosgs = fig.add_gridspec(nrows=2, ncols=2, height_ratios=[2, 1], width_ratios=[2, 1])
There we have very simply created our more complex grid layout with different heights and widths. So now, let’s use our last layout to create our final panelled figure:
# Stylingplt.style.use("seaborn-darkgrid")plt.rcParams["font.family"] = "Avenir"plt.rcParams["font.size"] = 16# Create Blank Figurefig = plt.figure(figsize=(10, 10))# Create 4x4 Gridgs = fig.add_gridspec(nrows=2, ncols=2, height_ratios=[2, 1], width_ratios=[2, 1])# Create Three Axes Objectsax1 = fig.add_subplot(gs[0, 0])ax2 = fig.add_subplot(gs[0, 1])ax3 = fig.add_subplot(gs[1, :])# Dummy Datax = np.linspace(0, 2*np.pi, 1000)# Plot Dataax1.plot(x, np.sin(x))ax2.plot(x, np.sin(x)**2)ax3.plot(x, np.sin(x) + np.cos(3*x))# Set axis labelsax1.set_ylabel("y", size=20)ax3.set_xlabel("x", size=20)ax3.set_ylabel("y", size=20)
And there we have it! We were able to create our panelled figure very simply using gridspec in matplotlib.
This was a very basic introduction to using gridspec to create your panelled figures with multiple plots. You can use the settings shown in this article to create some very sophisticated layouts, even taking advantage of using blank plots in some of the grid elements to create areas of space. The gridspec.ipynb notebook from this article will be available at this Github repository.
Thank you for reading! I appreciate any feedback, and you can find me on Twitter and connect with me on LinkedIn for more updates and articles.