1

I am trying to append rows of subplots to a Matplotlib figure inside a loop.

This works:

from sklearn.datasets import load_iris 
import numpy as np 
import pandas as pd 

iris_data = load_iris() 
join_pd_df = pd.DataFrame( 
  data = np.c_[ 
    iris_data['data'], 
    iris_data['target'], 
  ], 
  columns = iris_data['feature_names'] + ['target'] 
) 

import matplotlib.pyplot as plt 
import seaborn as sns 

list_of_features = [ 
  "sepal length (cm)", 
  "sepal width (cm)", 
  "petal length (cm)", 
] 

### I want to avoid this bit of pre-allocation
number_of_charts = 2 
number_of_features = len(list_of_features) 
arbitrarily_large_number_of_inches = 10 
fig, axes = plt.subplots( 
  number_of_features, 
  number_of_charts, 
  figsize=(arbitrarily_large_number_of_inches, arbitrarily_large_number_of_inches) 
) 
###:end I want to avoid this bit of pre-allocation

for iteration, feature in enumerate(list_of_features): 
  sns.regplot(x="target", y=feature, data=join_pd_df, ax=axes[iteration, 0]) 
  sns.boxplot(x=feature, y="target", data=join_pd_df, ax=axes[iteration, 1]) 

plt.subplots_adjust( 
  left = 0.1, 
  right = 0.9, 
  top = 0.9, 
  bottom = 0.1, 
  wspace = .4, 
  hspace = .4, 
) 

enter image description here

But I want to avoid pre-allocating the number of subplots and instead just append a row subplots to the bottom of the figure, so something along the lines of this:

from sklearn.datasets import load_iris 
import numpy as np 
import pandas as pd 

iris_data = load_iris() 
join_pd_df = pd.DataFrame( 
  data = np.c_[ 
    iris_data['data'], 
    iris_data['target'], 
  ], 
  columns = iris_data['feature_names'] + ['target'] 
) 

import matplotlib.pyplot as plt 
import seaborn as sns 

list_of_features = [ 
  "sepal length (cm)", 
  "sepal width (cm)", 
  "petal length (cm)", 
] 

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

for iteration, feature in enumerate(list_of_features, start=1): 
  ### I can't figure out what I'm doing wrong here because the subplots does not display properly
  correlation_chart_axes = fig.add_subplot(1, 2, 1) 
  sns.regplot(x="target", y=feature, data=join_pd_df, ax=correlation_chart_axes) 
  box_chart_axes = fig.add_subplot(1, 2, 2) 
  sns.boxplot(x=feature, y="target", data=join_pd_df, ax=box_chart_axes) 
  ###:end I can't figure out what I'm doing wrong here because the subplots does not display properly

plt.subplots_adjust( 
  left = 0.1, 
  right = 0.9, 
  top = 0.9, 
  bottom = 0.1, 
  wspace = .4, 
  hspace = .4, 
) 

enter image description here

Any tips or pointers on where to look for a newbie? Most of the articles I've found pre-allocate the number of rows and columns of subplots. Is appending to a Matplotlib figure something that just isn't done?

This post here: Dynamically add/create subplots in matplotlib suggests this bit of code:

number_of_subplots=3 # I want to avoid this preallocation
...
ax1 = subplot(number_of_subplots,1,v)
ax1.plot(x,y)

But it only adds subplots of 1 single column. I would like to add rows of subplots with 2 or more columns.

Thank you for your time

Zhao Li
  • 4,936
  • 8
  • 33
  • 51
  • I reread your question. I seems you just want to create `fig` and then add subplots within the loop. However, based on [Creating multiple subplots using plt.subplots](https://matplotlib.org/stable/gallery/subplots_axes_and_figures/subplots_demo.html) that's not an option. However, I'm going to reopen the question. – Trenton McKinney Aug 11 '21 at 03:40
  • Thank you for re-reading the question. Yes, I want to use a loop to append rows of plots to a `fig`. So each row corresponds to all the charts related to a specific feature. – Zhao Li Aug 11 '21 at 03:43
  • Maybe [In Matplotlib, what does the argument mean in fig.add_subplot(111)?](https://stackoverflow.com/q/3584805/7758804), but you're going to have to keep track of the positions – Trenton McKinney Aug 11 '21 at 03:43
  • Thanks, but I was hoping to just loop through the features and not really track the subplot positions. So each iteration of a loop corresponds to a single feature and a single row of charts. – Zhao Li Aug 11 '21 at 03:45
  • 1
    Thank you for all of your help. I've updated the code to include a full working example. Please let me know if you see any other areas where I can improve the code. I also added a screenshot of the output of the 2 different sets of code. Thanks again – Zhao Li Aug 11 '21 at 16:25

1 Answers1

0

It sounds like it's not possible at this time :(

Zhao Li
  • 4,936
  • 8
  • 33
  • 51