How to add already created figures to a subplot figure

Question:

I created this function that generates the ROC_AUC, then I returned the figure created to a variable.

from sklearn.metrics import roc_curve, auc
from sklearn.preprocessing import label_binarize
import matplotlib.pyplot as plt

def plot_multiclass_roc(clf, X_test, y_test, n_classes, figsize=(17, 6)):
    y_score = clf.decision_function(X_test)

    # structures
    fpr = dict()
    tpr = dict()
    roc_auc = dict()

    # calculate dummies once
    y_test_dummies = pd.get_dummies(y_test, drop_first=False).values
    for i in range(n_classes):
        fpr[i], tpr[i], _ = roc_curve(y_test_dummies[:, i], y_score[:, i])
        roc_auc[i] = auc(fpr[i], tpr[i])

    # roc for each class
    fig, ax = plt.subplots(figsize=figsize)
    ax.plot([0, 1], [0, 1], 'k--')
    ax.set_xlim([0.0, 1.0])
    ax.set_ylim([0.0, 1.05])
    ax.set_xlabel('False Positive Rate')
    ax.set_ylabel('True Positive Rate')
    ax.set_title('Receiver operating characteristic for Optimized SVC model')
    for i in range(n_classes):
        ax.plot(fpr[i], tpr[i], label='ROC curve (area = %0.2f) for label %i' % (roc_auc[i], i+1))
    ax.legend(loc="best")
    ax.grid(alpha=.4)
    sns.despine()
    plt.show()
    return fig

svc_model_optimized_roc_auc_curve = plot_multiclass_roc(svc_model_optimized, X_test, y_test, n_classes=3, figsize=(16, 10))

The resulting figure would look like somethin below:

ROC curve for SVC model

I created 5 different ROC curves for 5 different models using the same function but returning their figures to separate variables.

Then I created a subplot figure that I thought would display all of them. The code is:

import matplotlib.pyplot as plt
%matplotlib inline

figs, ax = plt.subplots(
    nrows=3,
    ncols=2,
    figsize=(20, 20),
)

ax[0,0] = logmodel_roc_auc_curve
ax[0,1] = RandomForestModel_optimized_roc_auc_cruve
ax[1,0] = decisiontree_model_optimized_roc_auc_curve
ax[1,1] = best_clf_knn_roc_auc_curve
ax[2,0] = svc_model_optimized_roc_auc_curve

But the resulting figure produced is this:

empty subplots

There was a similar problem to this here
but it was solved by executing the functions again. But I would like to find a way if possible to just simply "paste" the figures I already have into the subplot.

Asked By: JOHN EDWARD BINAY

||

Answers:

You need exactly the same as in the linked solution. You can’t store plots for later use. Note that in matplotlib a figure is the surrounding plot with one or more subplots. Each subplot is referenced via an ax.

Function plot_multiclass_roc needs some changes:

  • it needs an ax as parameter, and the plot should be created onto that ax.
  • fig, ax = plt.subplots(figsize=figsize) should be removed; the fig should be created previously, outside the function
  • also plt.show() should be removed from the function
  • it is not necessary to return anything

Outside the function, you create the fig and the axes. In matplotlib there is a not-well-followed convention to use axs for the plural of ax (when referring to a subplot). So:

fig, axs = plt.subplots(nrows = 3,
                        ncols = 2,
                        figsize= (20, 20)
                       )
plot_multiclass_roc(...., ax=axs[0,0]) # use parameters for logmodel
plot_multiclass_roc(...., ax=axs[0,1]) # use parameters for Random Forest
plot_multiclass_roc(...., ax=axs[1,0]) # ...
plot_multiclass_roc(...., ax=axs[1,1]) # ...
plot_multiclass_roc(...., ax=axs[2,0]) # ...
axs[2,1].remove() # remove the unused last ax
plt.tight_layout()  # makes that labels etc. fit nicely
plt.show()
Answered By: JohanC
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.