Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically add/create subplots in matplotlib

I want to create a plot consisting of several subplots with shared x/y axes. It should look something like this from the documentation (though my subplots will be scatterblots): (code here)

3 subplots sharing x and y axis

But I want to create the subplots dynamically!

So the number of subplots depends on the output of a previous function. (It will probably be around 3 to 15 subplots per diagram, each from a distinct dataset, depending on the input of my script.)

Can anyone tell me how to accomplish that?

like image 499
CodingCat Avatar asked Sep 07 '12 14:09

CodingCat


3 Answers

Suppose you know total subplots and total columns you want to use:

import matplotlib.pyplot as plt

# Subplots are organized in a Rows x Cols Grid
# Tot and Cols are known

Tot = number_of_subplots
Cols = number_of_columns

# Compute Rows required

Rows = Tot // Cols 

#     EDIT for correct number of rows:
#     If one additional row is necessary -> add one:

if Tot % Cols != 0:
    Rows += 1

# Create a Position index

Position = range(1,Tot + 1)

First instance of Rows accounts only for rows completely filled by subplots, then is added one more Row if 1 or 2 or ... Cols - 1 subplots still need location.

Then create figure and add subplots with a for loop.

# Create main figure

fig = plt.figure(1)
for k in range(Tot):

  # add every single subplot to the figure with a for loop

  ax = fig.add_subplot(Rows,Cols,Position[k])
  ax.plot(x,y)      # Or whatever you want in the subplot

plt.show()

Please note that you need the range Position to move the subplots into the right place.

like image 71
Matteo Scarponi Avatar answered Nov 02 '22 03:11

Matteo Scarponi


Based on this post, what you want to do is something like this:

import matplotlib.pyplot as plt

# Start with one
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot([1,2,3])

# Now later you get a new subplot; change the geometry of the existing
n = len(fig.axes)
for i in range(n):
    fig.axes[i].change_geometry(n+1, 1, i+1)

# Add the new
ax = fig.add_subplot(n+1, 1, n+1)
ax.plot([4,5,6])

plt.show() 

However, Paul H's answer points to the submodule called gridspec which might make the above easier. I am leaving that as an exercise for the reader ^_~.

like image 26
Sardathrion - against SE abuse Avatar answered Nov 02 '22 03:11

Sardathrion - against SE abuse


import matplotlib.pyplot as plt
from pylab import *
import numpy as np

x = np.linspace(0, 2*np.pi, 400)
y = np.sin(x**2)

subplots_adjust(hspace=0.000)
number_of_subplots=3

for i,v in enumerate(xrange(number_of_subplots)):
    v = v+1
    ax1 = subplot(number_of_subplots,1,v)
    ax1.plot(x,y)

plt.show()

This code works but you will need to correct the axes. I used to subplot to plot 3 graphs all in the same column. All you need to do is assign an integer to number_of_plots variable. If the X and Y values are different for each plot you will need to assign them for each plot.

subplot works as follows, if for example I had a subplot values of 3,1,1. This creates a 3x1 grid and places the plot in the 1st position. In the next interation if my subplot values were 3,1,2 it again creates a 3x1 grid but places the plot in the 2nd position and so forth.

like image 25
Harpal Avatar answered Nov 02 '22 03:11

Harpal