Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the facility exist within matplotlib to define subplot grids within subplots?

Tags:

matplotlib

I have a plot layout I want to use where 9 different clusters of data are laid out on a square grid. Each box in the grid contains 3 boxplots laid out side by side.

My initial thought is that this would fit a 3x3 subplot layout, with each individual subplot itself being divided into a 3x1 subplot layout.

I've seen this: Embedding small plots inside subplots in matplotlib which appears to let you define individual, manually placed plots inside subplots. However, the thought of recursively splitting up subplot space into grids of < 10 easily addressable subplots seems like such an obvious idea, I can't believe it's not been directly implemented.

like image 665
Thomas Kimber Avatar asked Feb 04 '23 11:02

Thomas Kimber


2 Answers

I think the nested gridspec example here is what you're seeking.

I've adapted their example to a mock-up of the grid pattern you described, which creates a list of axes using gridspec and then iterate over their indices to populate them. This approach should match your need for "a 3x3 subplot layout, with each individual subplot itself being divided into a 3x1 subplot layout."

import matplotlib as mpl
from matplotlib import gridspec
from matplotlib import pyplot as plt

f= plt.figure(figsize=(5, 5))
gs = gridspec.GridSpec(3, 3, wspace=0.5, hspace=0.2) #these are the 9 clusters

for i in range(9):
    nested_gs = gridspec.GridSpecFromSubplotSpec(1, 3, subplot_spec=gs[i], wspace=0.5) # 1 row, 3 columns for each cluster

    for j in range(3): #these are the 3 side by side boxplots within each cluster
        ax = plt.Subplot(f, nested_gs[j])
        ax.text(0.5, 0.5, "ax%d" % (i+1), va="center", ha="center", fontsize=9)
        
        #ax.boxplot(data) # this is where you'd add your boxplots to the axes
        
        # the following just cleans up each axes for readability
        for tl in ax.get_xticklabels():
            tl.set_visible(False)
        for tl in ax.get_yticklabels():
            tl.set_visible(False)
            if ax.is_first_col():
                tl.set_visible(True)
                tl.set_fontsize(9)
        f.add_subplot(ax)

f.savefig('nested_subplot.png')

I hope this helps get you started.

edited to include image:

enter image description here

like image 91
aorr Avatar answered Feb 07 '23 00:02

aorr


Matplotlib has a flat hierarchy. You have one figure and inside of that an undetermined and unbound number axes. A subplot of a subplot therefore does not exist. But of course you can place the axes such that they appear to be embedded inside other subplots.

What is possible though, is to use several layers of subplot grids. This is detailed in the gridspec guide. You may be especially interested in the use of GridSpecFromSubplotSpec, which allows to produce this example:

gs0 = gridspec.GridSpec(1, 2)

gs00 = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=gs0[0])
gs01 = gridspec.GridSpecFromSubplotSpec(3, 3, subplot_spec=gs0[1])

enter image description here

like image 38
ImportanceOfBeingErnest Avatar answered Feb 07 '23 00:02

ImportanceOfBeingErnest