14

I would like to create plot with many (100) subplots with Python matplotlib. I cannot find appropriate syntax for it:

I would like something like (this is not working)

plt.subplot(10,10,i,X1, Y) 

in a loop with i from 0 to 99, then

plt.show()

Syntax is available in many tutorials for case when there are only few subplots. Then, syntax can be

plt.close('all')
fig = plt.figure()

ax1 = plt.subplot(221)
ax2 = plt.subplot(223)
ax3 = plt.subplot(122)

example_plot(ax1)
example_plot(ax2)
example_plot(ax3)

plt.tight_layout()

code is from here.

For my problem, I guess that I cannot use the same syntax, as I would have plt.subplot(10101), etc., which I don't understand.

Do you have a solution?

Thanks

btel
  • 5,563
  • 6
  • 37
  • 47
kiriloff
  • 25,609
  • 37
  • 148
  • 229

5 Answers5

16

Try this:

fig, ax = plt.subplots(10, 10)

where ax will contain one hundred axis in a list (of lists).

It is a really handy function, from the docs:

Definition: plt.subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True, subplot_kw=None, **fig_kw)
Create a figure with a set of subplots already made.

This utility wrapper makes it convenient to create common layouts of
subplots, including the enclosing figure object, in a single call.
jorgeca
  • 5,482
  • 3
  • 24
  • 36
13

Here's a fully working code solution that shows how things are numbered, since it looks like people still come to look here:

columns = 10
rows = 4
fig, ax_array = plt.subplots(rows, columns,squeeze=False)
for i,ax_row in enumerate(ax_array):
    for j,axes in enumerate(ax_row):
        axes.set_title('{},{}'.format(i,j))
        axes.set_yticklabels([])
        axes.set_xticklabels([])
#         axes.plot(you_data_goes_here,'r-')
plt.show()

Which outputs this to show you how the numbering works (I only did 4 row instead of 10 to make the picture a bit smaller, just change "rows" to 10 to get 10 rows of subplots):

Matplotlib array of subplots

The numbering shows you what i and j values you'll have at each position so you can line things up the way you want in the array of matplotlib subplots. This incorporates subplotting in arrays for whatever layout you'd like.

Ezekiel Kruglick
  • 4,496
  • 38
  • 48
  • 2
    I know this is ancient but if you set rows or columns to 1, the code fails because there is nothing to iterate over. – Mr. Fegur Apr 09 '18 at 18:17
  • @Mr.Fegur - A fair enough point, although the whole point is showing a big array. Hopefully folks can see how to eliminate the unneeded loop if they want, do you want an example of that? – Ezekiel Kruglick Apr 10 '18 at 20:24
  • 1
    Perhaps editing your answer to include the squeeze='False' option in plt.subplots will make the answer handle the columns/row=1 case. – Mr. Fegur Apr 10 '18 at 23:50
  • @Mr.Fegur - Added. I hadn't ever had the occasion to use that, thank you for pointing me at it. neat! – Ezekiel Kruglick Apr 11 '18 at 01:18
  • See here for having one colorscale for all the subplots: https://stackoverflow.com/questions/13784201/matplotlib-2-subplots-1-colorbar – user3440489 Aug 27 '19 at 22:24
9

Your example is almost correct. Please use:

for i in range(100):
    ax = plt.subplot(10,10,i)
    ax.plot(...)
btel
  • 5,563
  • 6
  • 37
  • 47
4

If you are trying to generate ~100 subplots, as a practical matter you may want to do something like this which will run much faster. You give up have individual axes labels, but with 100 subplots, unless you are making huge print outs you won't be able to read the labels anyway.

Community
  • 1
  • 1
tacaswell
  • 84,579
  • 22
  • 210
  • 199
1

Here is a working example where you can choose the number of rows and columns to generate. In the example I generate random sine waves in random colors.

import numpy             as np
import matplotlib.pyplot as plt

cols = 5
rows = 20

x_data  = np.linspace(0,50,100)

fig, ax = plt.subplots(rows, cols, figsize=(40, 40), dpi=80)
for i in range(cols*rows):
    ax = plt.subplot(rows,cols,i+1)    
    ax.plot(x_data, random.uniform(0, 5)*np.sin(x_data+random.uniform(0, 2*np.pi)), 
            c= [random.uniform(0, 1),random.uniform(0, 1),random.uniform(0, 1)])

Image of the generated plot