How to dynamically plot multiple subplots in Python?

Question:

I need to plot a variable number of plots (at least 1 but it isn’t known the number max) and I couldn’t come up with a way to dynamically create and assign subplots to the given graphs.

The code looks like this:

check = False
    
    if "node_x_9" in names:
        if "node_x_11" in names:
            plt.plot(df["node_x_9"], df["node_x_11"])
            check = True
    elif "node_x_10" in names:
        if "node_x_12" in names:
            plt.plot(df["node_x_10", "node_x_12"])
            check = True
        
    if check:
        plt.show()

I thought about presetting a number of subplots (e.g. plt.subplots(3, 3)) but I still could not come up with a way to assign the plots without bounding them to a given subplot position.

My idea would be to create a 2×1 plot if I have two subplots, 1×1 if I have one, 3×1 if I have 3 and so on and not letting any subplot space empty.

Asked By: Enri Ventu

||

Answers:

I’ve come across cases like this, you want to generate one plot per case, but don’t know how many cases exist until you query the data on the day.

I used a square layout as an assumption (alter the below if you require a different aspect ratio) then count how many cases you have – find the integer square-root, which, plus one, will give you the integer side-length of a square that is guaranteed to fit your requirements.

Now, you can establish a matplotlib Gridspec object with the requisite width and height, referencing it by index to place your individual plots.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import gridspec
import random

# Create some random data with size=`random` number between 5 and 100
size = random.randint(5,100)
data_rows = pd.DataFrame([np.random.normal(1,5,25) for s in range(0,size)])

# Find the length of a (near) square based on the number of the data samples    
side_length = int(len(data_rows)**(1/2))+1
print(side_length)

#Create a gridspec object based on the side_length in both x and y dimensions
gs=gridspec.GridSpec(side_length, side_length)

fig = plt.figure(figsize=(10,10))

# Using the index i, populate the gridpsec object with 
# one plot per cell.
for i,row in data_rows.iterrows():
    ax=fig.add_subplot(gs[i])
    plt.bar(x=range(0,25),height=row)
    

example plot layout

Answered By: Thomas Kimber
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.