Reputation: 135
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()
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()
Upvotes: 2
Views: 121
Reputation: 1283
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:
set_visible(False)
figsize=(20,7)
on top you can adapt the overal plot size
ax2.get_yaxis().set_visible(False)
by ax2.tick_params(axis='y', label1On=False)
Here's a screenshot incl. some jupyter parts to show that both overall plots have the same size:
Upvotes: 1