Home > Software design >  Need to plot a number of graphs in a grid from a for loop creation
Need to plot a number of graphs in a grid from a for loop creation

Time:11-18

I have a straightforward for loop that loops through datasets in a set and plots the resultant scatterplot for each dataset using the code below;

for i in dataframes:
    x = i['cycleNumber']
    y = i['QCharge_mA_h']

    plt.figure()
    sns.scatterplot(x=x, y=y).set(title=i.name) 

This plots the graphs out as expected, one on top of the other. Is there a simple way to get them all to plot onto a grid for better readability?

As an example lets say we have the following datasets and code:

data1 = {'X':[12, 10, 20, 17], 'Y':[9, 8, 5, 3]}  
data2 = {'X':[2, 13, 7, 21], 'Y':[17, 18, 4, 6]}  
data3 = {'X':[9, 19, 20, 3], 'Y':[6, 12, 4, 1]}  
data4 = {'X':[10, 13, 15, 1], 'Y':[6, 12, 5,16]}  
data5 = {'X':[12, 10, 5, 3], 'Y':[18, 7, 21, 7]}  
data6 = {'X':[5, 10, 8, 17], 'Y':[9, 12, 5, 18]}

df1=pd.DataFrame(data1)
df2=pd.DataFrame(data2)
df3=pd.DataFrame(data3)
df4=pd.DataFrame(data4)
df5=pd.DataFrame(data5)
df6=pd.DataFrame(data6)

lst = [df1, df2, df3, df4, df5, df6]

for i in lst:
    plt.figure()
    sns.scatterplot(x=i['X'], y=i['Y'])

This returns an output of each scatterplot called printing on top of another i.e. stacked. I cant upload a shot of what that output looks like as it runs across multiple pages (this tidy output that I can capture and display is exactly what it is I'm trying to achieve).

I want it to be in a grid, lets say a 2x3 grid given it has 6 plots. How do I achieve this?

CodePudding user response:

Few ways you could do this.

The Original

import matplotlib  # 3.6.0
from matplotlib import pyplot as plt
import numpy as np  # 1.23.3
import pandas as pd  # 1.5.1
import seaborn as sns  # 0.12.1


# make fake data
df = pd.DataFrame({
    "cycleNumber": np.random.random(size=(100,)),
    "QCharge_mA_h": np.random.random(size=(100,)),
})

# single plot
fig, ax = plt.subplots()
sns.scatterplot(df, x="cycleNumber", y="QCharge_mA_h", ax=ax)
plt.show()

original

With matplotlib

# make 5 random data frames
dataframes = []
for i in range(5):
    np.random.seed(i)
    random_df = pd.DataFrame({
        "cycleNumber": np.random.random(size=(100,)),
        "QCharge_mA_h": np.random.random(size=(100,)),
    })
    dataframes.append(random_df)

# make len(dataframes) rows using matplotlib
fig, axs = plt.subplots(nrows=len(dataframes))
for df, ax in zip(dataframes, axs):
    sns.scatterplot(df, x="cycleNumber", y="QCharge_mA_h", ax=ax)

plt.show()

mpl

With seaborn

# make 5 random data frames
dataframes = []
for i in range(5):
    np.random.seed(i)
    random_df = pd.DataFrame({
        "cycleNumber": np.random.random(size=(100,)),
        "QCharge_mA_h": np.random.random(size=(100,)),
    })
    dataframes.append(random_df)

# make len(dataframes) rows using matplotlib

# concat dataframes
dfs = pd.concat(dataframes, keys=range(len(dataframes)), names=["keys"])

# move keys to columns
dfs = dfs.reset_index(level="keys")

# make grid and map scatterplot to each row
grid = sns.FacetGrid(data=dfs, row="keys")
grid.map(sns.scatterplot, "cycleNumber", "QCharge_mA_h")
plt.show()

sns

With col_wrap=3

# make 5 random data frames
dataframes = []
for i in range(5):
    np.random.seed(i)
    random_df = pd.DataFrame({
        "cycleNumber": np.random.random(size=(100,)),
        "QCharge_mA_h": np.random.random(size=(100,)),
    })
    dataframes.append(random_df)

# make len(dataframes) rows using matplotlib

# concat dataframes
dfs = pd.concat(dataframes, keys=range(len(dataframes)), names=["keys"])

# move keys to columns
dfs = dfs.reset_index(level="keys")

# make grid and map scatterplot to each column, wrapping after 3
grid = sns.FacetGrid(data=dfs, col="keys", col_wrap=3)
grid.map(sns.scatterplot, "cycleNumber", "QCharge_mA_h")
plt.show()

col_wrap

  • Related