Customizing Multiple Subplots in Matplotlib | by Rizky Maulana N | Towards Data Science

In certain times, we need to visualize our data into complex plots because we should do it or make a great plot. For example, you want to make a zoom effect in your plot, as shown in Figure 1. To present it, you need to build a convoluted subplot. Figure 1 is built from three different axes: axes1, axes2, and axes3. Axes1 is on the top-left panel, showing the data in green plot lines, axes2 is on the top-right panel with orange lines, and the biggest one, axes3 lies on the bottom panel.
Before creating complex plots, you need to know the difference between the terms figure and axes in Matplotlib. To do it, you can learn about the anatomy of a figure defined in Matplotlib, as shown in Figure 2.
Figure is defined as the main container for all elements, such as axes, legend, title, etc. A figure can contain some axes (we will learn in more in-depth about it). In Figure 1, we have only one figure, which contains three axes. If you want to create a zoom effect in Maptlotlib, you visit this link.
towardsdatascience.com
In this section, we will learn about the fundamental of the subplot in Matplotlib. Some examples that I will show you are not realistic plots, but it will become good examples to understand the subplot.
To create axes, you can use at least two different methods. First, you can use the syntax subplot, and the second one is using gridspec. At the beginning of the learning subplot, I will show you a simple subplot, as shown in Figure 3.
You can generate Figure 3 using the following code
import matplotlib.pyplot as pltfig = plt.figure()coord = 111plt.subplot(coord)plt.annotate('subplot ' + str(coord), xy = (0.5, 0.5), va = 'center', ha = 'center')
One of the important things to understand the subplot in Matplotlib is defining the coordinate of the axes. The variable coord in the code above is 111. It consists of three numbers representing the number of rows, columns, and the axes’ sequence. coord 111 means, you generate a figure that consists of one row, one column, and you insert the subplot in the first sequence axes. Because you only have one row and one column (it means you only have one cell), your axes are the main figure. You also can generate Figure 3 without subplot syntax because you only generate one axes in a figure.
Next step is creating two horizontal axes in a figure, as shown in Figure 4. You can use this code to generate it
fig = plt.figure(figsize=(12, 4))coord1 = 121coord2 = 122plt.subplot(coord1)plt.annotate('subplot ' + str(coord1), xy = (0.5, 0.5), va = 'center', ha = 'center')plt.subplot(coord2)plt.annotate('subplot ' + str(coord2), xy = (0.5, 0.5), va = 'center', ha = 'center')
You need to define the figure size to create a nice two horizontal axes. If you did not do it, you would get a figure like a Figure 5.
If you want to create two vertical axes, you just change the coord1 and coord2, as shown in the following code
fig = plt.figure(figsize=(6, 7))coord1 = 211coord2 = 212plt.subplot(coord1)plt.annotate('subplot ' + str(coord1), xy = (0.5, 0.5), va = 'center', ha = 'center')plt.subplot(coord2)plt.annotate('subplot ' + str(coord2), xy = (0.5, 0.5), va = 'center', ha = 'center')
Now, I will try to create more subplot in a figure using looping. I will create 2x4 axes, as shown in Figure 6.
You can reproduce Figure 6 using this code
fig = plt.figure(figsize=(16, 6))coord = []# create coord array from 241, 242, 243, ..., 248 for i in range(1, 9): # in python, 9 is not included    row = 2    column = 4    coord.append(str(row)+str(column)+str(i))    # create subplot 241, 242, 243, ..., 248for i in range(len(coord)):    plt.subplot(coord[i])    plt.annotate('subplot ' + str(coord[i]), xy = (0.5, 0.5), va = 'center', ha = 'center')
Because you want to create 8 axes (2 rows and 4 columns), so you need to make an array from 241 to 248. After that, create the subplot using the same procedure with the previous code, but place it in looping syntax.
As I mentioned before, besides using subplot to create some axes in a figure, you can also use gridspec. For example, if you want to create Figure 6 (two rows and 4 columns) with gridspec, you can use this code
import matplotlib.pyplot as pltfig = plt.figure(figsize=(16, 6))rows = 2columns = 4grid = plt.GridSpec(rows, columns, wspace = .25, hspace = .25)for i in range(rows*columns):    exec (f"plt.subplot(grid{[i]})")    plt.annotate('subplot 24_grid[' + str(i) + ']', xy = (0.5, 0.5), va = 'center', ha = 'center')
To create simple subplot using gridspec, you define the number of rows and columns in the beginning. To embed the subplot into figure, you just call the number of subplot. In gridspec, number of subplot is starting from 0, not 1. So, if you want to embed 8 columns in a figure using gridspec, you need to call them from 0 to 7, using plt.subplot(grid[0]) until plt.subplot(grid[7]). In the looping, you will get an issue because you want to call grid number using []. To deal with it, you can use syntax exec (f”...{[i]}”).
Figure 7 is the result of creating 8 axes using gridspec
One of the advantages of using gridspec is you can create more subplots in an easier way than that using subplot only. For example, if you want to create more than 10 subplots in a figure, you will define the last coordinates. The subplot only consists of three numbers, e.g., 111, 428, 439, etc. A subplot can not facilitate the fourth. For example, you want to create 18 axes (3 rows and 6 columns) in a figure. If you use subplot only, you need to define 361, 362, 263, ..., 3616. You will face the error when you embed a subplot of 3610. To solve it, you can use gridspec. Figure 8 is presenting the creation of 18 axes using gridspec.
You can create Figure 8 with this code
fig = plt.figure(figsize=(22, 8))rows = 3columns = 6grid = plt.GridSpec(rows, columns, wspace = .25, hspace = .25)for i in range(rows*columns):    exec (f"plt.subplot(grid{[i]})")    plt.annotate('subplot 36_grid[' + str(i) + ']', xy = (0.5, 0.5), va = 'center', ha = 'center')
To make a more realistic example, I will insert a plot for each axes in Figure 8. So, I need to make 18 different functions for each axes. It is compiled from the function of sin(x^(i/9)), with i is the grid number from 0 to 17. You can see the plot in Figure 9.
To create Figure 9, you can use the following code
fig = plt.figure(figsize=(25, 10))color = ['#00429d', '#2754a6', '#3a67ae', '#487bb7', '#548fc0',          '#5ea3c9', '#66b8d3', '#6acedd', '#68e5e9', '#ffe2ca',          '#ffc4b4', '#ffa59e', '#f98689', '#ed6976', '#dd4c65',          '#ca2f55', '#b11346', '#93003a']rows = 3columns = 6grid = plt.GridSpec(rows, columns, wspace = .25, hspace = .25)for i in range(rows*columns):    np.random.seed(100)    x = np.linspace(0., 5., 100)    y = np.sin(x**(i / 9)) + np.random.random() * i        exec (f"plt.subplot(grid{[i]})")        plt.plot(x, y, color = color[i])
To present in different colors, you also need to define 18 different colors. You can generate it using this link. I have explained how to use it in the following link.
towardsdatascience.com
In this section, we will learn about customizing complicated axes using add_subplot and GridSpec. The complicated axes I mentioned are shown in Figure 10.
We will create 3 axes (2 on the top, 1 on the bottom panel) as shown in Figure 1 using add_subplot syntax. You can use this code to create it.
If you analyze the code, you will get a similar concept with the subplot syntax concept. There are three coordinates you need to define, e.g., (2, 2, 1) or (2, 2, (3, 4)). The axes sub1 is placed in the first axes (1) on the figure that consists of 2 rows and 2 columns. sub2 has similar schemes with sub1. The important one is sub3, which the combination between axes 3 and 4. So, the coordinate of sub3 is (2, 2, (3, 4)). If you run the code above, you will get a result, as shown in Figure 11.
If you want to add a plot for each ax, you can add this code after defining sub1, sub2, and sub3.
sub1.plot(x, y)sub2.plot(x, y)sub3.plot(x, y)
The full code is here.
You will get a result, as shown in Figure 12.
As an alternative, you can also create Figure 12 using gridspec syntax. Here is the code you can use to create it.
The code creates 2 rows and 2 columns. sub1 and sub2 are placed on the first row, column 0 and column 1 (remember that gridspec is started from 0 indexes). sub3 is placed on the second row and takes all of the columns, represented by :. You will get the same plot, as shown in Figure 12, if you run the code above.
The second example of complicated axes is shown in Figure 13.
You will generate four axes in a figure: sub1, sub2, sub3, and sub4, in 2 rows and 4 columns. sub1 takes all the columns in the first row. sub2, sub3, and sub4 are placed on each column in the second row. To generate Figure 12, you can use this code.
To create Figure 12 using gridspec, you can use this code.
I think the code above is clear enough to be understood :D. The code will generate a plot, as shown in Figure 14.
The third example is shown in Figure 15.
To create Figure 15, you can use this code.
To create Figure 15 using gridspec, you can use this code.
The result is shown in Figure 16.
In the last example, you will be guided to create 6 axes in a figure, with the number of rows is 4 and columns is 2. It is shown in Figure 17.
To create it with add_subplot, you can use the following code.
To create Figure 17 with gridspec, you can use this code.
You need to pay attention to sub4, which is placed in rows 1:3 and column 1. Rows 1:3 means that sub4 will take rows number 1 and 2. Remember, rows 3 is not included. The code will generate a plot, as shown in Figure 17.
Creating a complex plot to visualize your data is needed while you are working with complex data. I hope this story can help you to visualize your data from a different point of view. If you need to create scientific publication plots with Matplotlib, you can visit this link.
towardsdatascience.com
towardsdatascience.com
towardsdatascience.com
towardsdatascience.com
towardsdatascience.com
That’s all. Thanks for reading this story. Comment and share if you like it. I also recommend you follow my account to get a notification when I post my new story.