0

I have a Subplots with Confusion Matrixes which are presented with HeatMap.

Subplot with Heatmaps I would like to adjust the graph to be more readible and do things like:

1) Add one big title above columns 'Targets'

2) Add one big Ylabel 'Predictions'

3) for each column have only one big legend, since they are showing the same thing

4 ) for each column add column names ['Train CM', 'Train Norm CM', 'Validation CM', 'Validation Norm CM'] and row names [f'Epoch {i}' for i in range(n_epoch)]. I did like in here but only work for columns and not for rows, I dont know why.

My code:

cols = ['Train CM', 'Train Norm CM', 'Validation CM', 'Validation Norm CM']
rows = [f'Epoch {i}' for i in range(n_epoch)]

f, axes  = plt.subplots(nrows = n_epoch, ncols = 4, figsize=(40, 30))
for ax, col in zip(axes [0], cols):
    ax.set_title(col, size='large')

for ax, row in zip(axes[:,0], rows):
    ax.set_ylabel(row, rotation=0, size='large')

f.tight_layout()

for e in range(n_epoch):
    for c in range(4):
        # take conf matrix from lists cm_Train or cm_Validation of ConfusionMatrix() objects
        if c == 0:
            cm = np.transpose(np.array([list(item.values()) for item in cm_Train[e].matrix.values()]))
        elif c == 1:
            cm = np.transpose(np.array([list(item.values()) for item in cm_Train[e].normalized_matrix.values()]))
        elif c == 2:
        cm = np.transpose(np.array([list(item.values()) for item in cm_Validation[e].matrix.values()]))
    else:
        cm = np.transpose(np.array([list(item.values()) for item in cm_Validation[e].normalized_matrix.values()]))
    sns.heatmap(cm, annot=True, fmt='g', ax = axes[e, c], linewidths=.3)
Sheldore
  • 37,862
  • 7
  • 57
  • 71
user0810
  • 886
  • 5
  • 19
  • 33

1 Answers1

1

I am presenting a solution with empty plots because I don't have your data. Is this what you want:

n_epoch = 4
cols = ['Train CM', 'Train Norm CM', 'Validation CM', 'Validation Norm CM']
rows = [f'Epoch {i}' for i in range(n_epoch)]

f, axes  = plt.subplots(nrows = n_epoch, ncols = 4, figsize=(12, 8))

f.text(0, 0.5, 'Predictions', ha='center', va='center', fontsize=20, rotation='vertical')
plt.suptitle("One big title", fontsize=18, y=1.05)

for ax, col in zip(axes [0], cols):
    ax.set_title(col, size='large')

for ax, row in zip(axes[:, 0], rows):
    ax.set_ylabel(row, size='large')

plt.tight_layout()    

enter image description here

Putting color bars: Here you put the colorbars spanning all the rows for each column. However, here the tight_layout() isn't compatible so you will have to turn it off.

f, axes  = plt.subplots(nrows = n_epoch, ncols = 4, figsize=(12, 8))

for i, ax in enumerate(axes.flat):
    im = ax.imshow(np.random.random((20,20)), vmin=0, vmax=1)
    if i%4 == 0:
        f.colorbar(im, ax=axes[:,int(i/4)].ravel().tolist(), aspect=30, pad=0.05)    

f.text(0.08, 0.5, 'Predictions', ha='center', va='center', fontsize=20, rotation='vertical')
plt.suptitle("One big title", fontsize=18)

for ax, col in zip(axes [0], cols):
    ax.set_title(col, size='large')

for ax, row in zip(axes[:, 0], rows):
    ax.set_ylabel(row, size='large')

enter image description here

Sheldore
  • 37,862
  • 7
  • 57
  • 71
  • looks fine, but still it does not show the y_labels – user0810 Jan 03 '19 at 15:06
  • You haven't made it clear where and how you want to show the y-labels. Currently Epoch0, Epoch 1 etc. ARE the y-labels – Sheldore Jan 03 '19 at 15:07
  • Ah yes, maybe I didnt explain well, each row is an epoch so y_label for whole first row should be Epoch1, 2nd row Epoch 2 and so on – user0810 Jan 03 '19 at 15:08
  • Ok, I edited my solution. Check the edited figure. By the way, you are supposed to ask one problem typically on SO in your question. Here you have asked 4 different questions. – Sheldore Jan 03 '19 at 15:11
  • I see your change, and it is similar like in the link I gave, but for some reason the y_labels do not appear – user0810 Jan 03 '19 at 15:13
  • What do you mean by "the y_labels do not appear"? Aren't they visible in the figure in my answer? What is a y-label for you? Epoch 0 Epoch 1... are CLEARLY visible in the figure. You are simply confusing things now – Sheldore Jan 03 '19 at 15:14
  • In your example are visible, but in MY subplot I am creating they do not appear, even if I am using the same code – user0810 Jan 03 '19 at 15:16
  • @goskan: Check the edit to answer your last question on colorbars – Sheldore Jan 03 '19 at 15:58
  • constrained_layout is compatible with those colorbars... Oops, not very compatible.... – Jody Klymak Jan 10 '19 at 06:10