Home > database >  One figure with two subplots and one with three do not have the same size
One figure with two subplots and one with three do not have the same size

Time:09-06

I am trying to create two figures with squared subfigures for an article. My problem is that when I do it for two subfigures I get one size and when I do it for three I get a different one, and I would like both to have the same overall size. Moreover, I would like to have all subfigures touching each other as in the examples below.

I am sharing the codes and the outputs for both cases.

Two subfigures:

fig, ax = plt.subplots(1,2, figsize=(13,7), sharey=True, facecolor='w')
fig.subplots_adjust(wspace=0, hspace=0)

ax[0].scatter(exp_list, yrel_slack_list, label='CCC; R$^2$ = 0.34, MUE = 1.01')
ax[0].scatter(exp_list, yrel_glm1_list, facecolors='none', edgecolors='#ff7f0e', label='CCC   cGLM1; R$^2$ = 0.81, MUE = 0.56')
ax[0].plot(np.linspace(-4,4), np.linspace(-4,4), color='red')

ax[1].scatter(exp_list, yrel_slack_list, label='CCC; R$^2$ = 0.34, MUE = 1.01')
ax[1].scatter(exp_list, yrel_slm1_list, facecolors='none', edgecolors='#8c564b', label='CCC   cSLM1; R$^2$ = 0.40, MUE = 0.77')
ax[1].plot(np.linspace(-4,4), np.linspace(-4,4), color='red')

ax[0].set_ylabel(r'Estimated $\Delta \Delta G$ (kcal/mol)', fontsize=14)
ax[0].set_xlabel('Experimental $\Delta \Delta G$ (kcal/mol)', fontsize=14)
ax[0].legend(loc=0, frameon=False, fontsize=14, handletextpad=0.1)
ax[0].set_ylim([-4,1])
ax[0].set_xlim([-4,1])
ax[0].set_xticks([-4, -3, -2, -1, 0])
ax[0].tick_params(axis = 'both', which = 'major', labelsize=14)
ax[1].set_xlim([-4,1])
ax[1].legend(loc=0, frameon=False, fontsize=14, handletextpad=0.1)
ax[1].set_xlabel('Experimental $\Delta \Delta G$ (kcal/mol)', fontsize=14)
ax[1].tick_params(axis = 'both', which = 'major', labelsize=14)

plt.savefig('inclusion_1h1q_correlation.eps', format='eps', bbox_inches='tight')
plt.show()

enter image description here

Three subfigures:

fig, ax = plt.subplots(1,3, figsize=(20,7), sharey=True, facecolor='w')
fig.subplots_adjust(wspace=0, hspace=0)

ax[0].scatter(exp_list, yrel_slack_list, marker='x', color='k', label='CCC; R$^2$ = 0.34, MUE = 1.01')
ax[0].scatter(exp_list, yrel_c1oiu1h1q_list, color='#1f77b4', label='CCC   cGLM1; R$^2$ = %.2f, MUE = %.2f'%(corr_node_c1oiu1h1q[0]**2,corr_node_c1oiu1h1q[1]))
ax[0].plot(np.linspace(-4,1), np.linspace(-4,1), color='red')

ax[1].scatter(exp_list, yrel_slack_list, marker='x', color='k', label='CCC; R$^2$ = 0.34, MUE = 1.01')
ax[1].scatter(exp_list, yrel_c1oiu1h1q_c1oiu1h1s_list, color='#ff7f0e', label='CCC   cGLM1-2; R$^2$ = %.2f, MUE = %.2f'%(corr_node_c1oiu1h1q_c1oiu1h1s[0]**2,corr_node_c1oiu1h1q_c1oiu1h1s[1]))
ax[1].plot(np.linspace(-4,1), np.linspace(-4,1), color='red')

ax[2].scatter(exp_list, yrel_slack_list, marker='x', color='k', label='CCC; R$^2$ = 0.34, MUE = 1.01')
ax[2].scatter(exp_list, yrel_c1h1q1oiu_i1oiu_list, color='#2ca02c', label='CCC   cGLM1   iGLMI1; R$^2$ = %.2f, MUE = %.2f'%(corr_node_1oiu[0]**2,corr_node_1oiu[1]))
ax[2].plot(np.linspace(-4,1), np.linspace(-4,1), color='red')

ax[0].set_ylabel(r'Estimated $\Delta \Delta G$ (kcal/mol)', fontsize=18)
ax[0].set_xlabel('Experimental $\Delta \Delta G$ (kcal/mol)', fontsize=18)
ax[0].legend(loc=0, frameon=False, fontsize=12, handletextpad=0.1)
ax[0].set_ylim([-3.5,1])
ax[0].set_xlim([-3.5,1])
ax[0].tick_params(axis = 'both', which = 'major', labelsize=18)
ax[1].set_xlim([-3.5,1])
ax[1].legend(loc=0, frameon=False, fontsize=12, handletextpad=0.1)
ax[1].set_xlabel('Experimental $\Delta \Delta G$ (kcal/mol)', fontsize=18)
ax[1].tick_params(axis = 'both', which = 'major', labelsize=18)
ax[2].set_xlim([-3.5,1])
ax[2].legend(loc=0, frameon=False, fontsize=12, handletextpad=0.1)
ax[2].set_xlabel('Experimental $\Delta \Delta G$ (kcal/mol)', fontsize=18)
ax[2].tick_params(axis = 'both', which = 'major', labelsize=18)

plt.savefig('main_result_cdk2.eps', format='eps', bbox_inches='tight')
plt.show()

enter image description here

CodePudding user response:

You can use gridspec to align subplots ratios for a given overall figure size incl. your required y-axis touching.

I haven't adapted all your various individual plot settings, but tried to show how gridspec can be used for your general case and kept the respective parts like e.g. the axis ticks (to not overlap especially at the shared y-axis).

from matplotlib import gridspec

### 2 subplots
fig = plt.figure(figsize=(20,7), facecolor='w')
fig.subplots_adjust(wspace=0, hspace=0)

gs = gridspec.GridSpec(1, 2, width_ratios=[1,1]) 
ax1 = fig.add_subplot(gs[0,:1])
ax1.set_title('ax1')
ax1.set_ylim([-4,1])
ax1.set_xlim([-4,1])
ax1.set_xticks([-4, -3, -2, -1, 0])

xx, locs = plt.yticks()
ll = ['%.1f' % a for a in xx]
ax1.set_yticks(xx, ll)

ax1.tick_params(axis = 'both', which = 'major', labelsize=14)
ax2 = fig.add_subplot(gs[0,1:])
ax2.set_title('ax2')
ax2.get_yaxis().set_visible(False)
ax2.set_xlim([-4,1])
ax2.tick_params(axis = 'both', which = 'major', labelsize=14)

ax1.set_ylabel(r'Estimated $\Delta \Delta G$ (kcal/mol)', fontsize=14)
ax1.set_xlabel('Experimental $\Delta \Delta G$ (kcal/mol)', fontsize=14)
ax2.set_xlabel('Experimental $\Delta \Delta G$ (kcal/mol)', fontsize=14)

plt.show()

### 3 subplots
fig = plt.figure(figsize=(20,7), facecolor='w')
fig.subplots_adjust(wspace=0, hspace=0)

gs = gridspec.GridSpec(1, 3, width_ratios=[1,1,1]) 
ax1 = fig.add_subplot(gs[0,:1])
ax1.set_title('ax1')
ax1.set_ylim([-3.5,1])
ax1.set_xlim([-3.5,1])
ax1.tick_params(axis = 'both', which = 'major', labelsize=14)
ax2 = fig.add_subplot(gs[0,1])
ax2.set_title('ax2')
ax2.get_yaxis().set_visible(False)
ax2.set_xlim([-3.5,1])
ax2.tick_params(axis = 'both', which = 'major', labelsize=14)
ax3 = fig.add_subplot(gs[0,2:])
ax3.set_title('ax3')
ax3.get_yaxis().set_visible(False)
ax3.set_xlim([-3.5,1])
ax3.tick_params(axis = 'both', which = 'major', labelsize=14)

ax1.set_ylabel(r'Estimated $\Delta \Delta G$ (kcal/mol)', fontsize=14)
ax1.set_xlabel('Experimental $\Delta \Delta G$ (kcal/mol)', fontsize=14)
ax2.set_xlabel('Experimental $\Delta \Delta G$ (kcal/mol)', fontsize=14)
ax3.set_xlabel('Experimental $\Delta \Delta G$ (kcal/mol)', fontsize=14)

plt.show()

Notes:

  • The inner y-axes need the set_visible(False)
  • With figsize=(20,7) on top you can adapt the overal plot size
    • You may align that if you need more squared subplots and accept different heights for that at a given overall width.
  • If you want to keep the ticks on the connected y-axes but only want to remove the label you can replace ax2.get_yaxis().set_visible(False) by ax2.tick_params(axis='y', label1On=False)
  • Items to fine tune the optical width on the left y-axis - adapt those acc. your preference.
    • I notized you had different font sizes and aligned them.
    • At the 2 subplots y-axis floats with 1 decimal point is included (as given by the 3 subplots y-axis), you can remove that part again easily if it's not intended.

Here's a screenshot incl. some jupyter parts to show that both overall plots have the same size:

enter image description here

  • Related