0

I'm trying to display a figure that contains 3 plots, and each of the plots is a plot of (8,1)-shaped subplots.

Essentially, I want one big figure with three sections each containing (8,1)-shaped subplots.

I'm looking for a way to do this without having to manually set all the proportions and spacings. The reason I'm doing this is to visualize an 8-channel neural signal compared to three other pre-defined signals, each signal being 8 channels.

If it makes any sense this way, I'm trying for something like this (ficticious code):

fig, ax = plt.subplots(n_figures = 3, n_rows = 8, n_cols = 1)
ax[figure_i, row_j, col_k].imshow(image)

Is there a way to do this?


Here is an example of what I am talking about. Ideally it would three subplots, and in each of the subplots there is a set of subplots of shape 8x1. I understand how to plot this all out by going through all the margins and setting the proportions, but I'm wondering if there's a simpler way to do this without having to go through all the additional code and settings as described in the above example code I've written.

enter image description here

Oliver G
  • 375
  • 1
  • 3
  • 16
  • I think the cited duplicate gives you the multiple subplots in the original question, and the answers help with your page layout. If not, toss a clarifying comment here, and I'll reopen. – Prune Apr 11 '20 at 17:59
  • Unfortunately the cited duplicate does not answer my question, as I am looking for subplots within subplots. As an example, in the accepted answer of the cited duplicate there is a picture of a 4x4-subplot graph within the figure. If there is a way to plot an 8x1 subplot within each of the 4x4 subplots without specifically adding more subplots manually and then adjusting the margins to make it look as if it is three separate figures concatenated together, then that would answer my question. – Oliver G Apr 11 '20 at 18:24
  • It sounds to me as if you're simply trying to graph several sets of data in one plot, not make separate sub-plots. – Prune Apr 11 '20 at 19:27
  • Perhaps you could sketch your intended plot and upload as an image here? – Arne Apr 11 '20 at 19:44
  • @Arne I have added a sketch of what I am talking about. I'm specifically looking for a way to do this without having to modify all the sizes and spacings and without having to plot each graph separately for comparison. – Oliver G Apr 11 '20 at 20:14
  • Thanks for the sketch. I still don't understand why you don't want to use an 8x3 grid of 24 subplots. You could perhaps loop over the rows and columns of the grid to create the subplots. – Arne Apr 11 '20 at 20:36

1 Answers1

0

You can create this kind of figure by first creating a subplot grid with the appropriate layout using the plt.subplots() function and then looping through the array of axes to plot the data, like in this example:

import numpy as np                 # v 1.19.2
import matplotlib.pyplot as plt    # v 3.3.2

# Create sample signal data as a 1-D list of arrays representing 3x8 channels
signal_names = ['X1', 'X2', 'X3']
nsignals = len(signal_names)  # ncols of the subplot grid
nchannels = 8  # nrows of the subplot grid
nsubplots = nsignals*nchannels
x = np.linspace(0, 14*np.pi, 100)
y_signals = nsubplots*[np.cos(x)]

# Set subplots width and height
subp_w = 10/nsignals  # 10 corresponds the figure width in inches
subp_h = 0.25*subp_w

# Create figure and subplot grid with the appropriate layout and dimensions
fig, axs = plt.subplots(nchannels, nsignals, sharex=True, sharey=True,
                        figsize=(nsignals*subp_w, nchannels*subp_h))

# Optionally adjust the space between the subplots: this can also be done by
# adding 'gridspec_kw=dict(wspace=0.1, hspace=0.3)' to the above function
# fig.subplots_adjust(wspace=0.1, hspace=0.3)

# Loop through axes to create plots: note that the list of axes is transposed
# in this example to plot the signals one after the other column-wise, as
# indicated by the colors representing the channels
colors = nsignals*plt.get_cmap('tab10').colors[:nchannels]
for idx, ax in enumerate(axs.T.flat):
    ax.plot(x, y_signals[idx], c=colors[idx])
    if ax.is_first_row():
        ax.set_title(signal_names[idx//nchannels], pad=15, fontsize=14)

plt.show()

subplot_grid

Patrick FitzGerald
  • 3,280
  • 2
  • 18
  • 30