I am thinking on a plot that contains 3 rows and 4 columns, where:
There are 3 dependent variables to plot: Y1
, Y2
and Y3
, versus a common X
independent variable, for 4 cases of study:
In this situation there is:
1) a sharing of y
axis when going from case i
to case i+1
2) a sharing of x
axis within a case i
Thus, in principle, one would think that the following code will produce the desired plot (result shown in the upper image):
fig, axes = plt.subplots(ncols=4, nrows=3,\
sharex=True, sharey=True,\
subplot_kw=dict(adjustable='box-forced'))
where the adjustable='box-forced'
is just to ensure that the subplots are squared, as explained here.
When I try to plot Y1
versus X
for case 1:
import numpy as np
import matplotlib.pyplot as plt
import sys
fig, axes = plt.subplots(ncols=4, nrows=3,\
sharex=True, sharey=True,\
subplot_kw=dict(adjustable='box-forced'))
pad = 5
axes[0][0].annotate('Case 1', xy=(0.5, 1), xytext=(0, pad),
xycoords='axes fraction', textcoords='offset points',
size='large', ha='center', va='baseline')
axes[0][1].annotate('Case 2', xy=(0.5, 1), xytext=(0, pad),
xycoords='axes fraction', textcoords='offset points',
size='large', ha='center', va='baseline')
axes[0][2].annotate('Case 3', xy=(0.5, 1), xytext=(0, pad),
xycoords='axes fraction', textcoords='offset points',
size='large', ha='center', va='baseline')
axes[0][3].annotate('Case 4', xy=(0.5, 1), xytext=(0, pad),
xycoords='axes fraction', textcoords='offset points',
size='large', ha='center', va='baseline')
#
axes[0][0].set_ylabel('Y1', fontsize=10)
axes[1][0].set_ylabel('Y2', fontsize=10)
axes[2][0].set_ylabel('Y3', fontsize=10)
E_C_I = np.array([-941.23658347, -941.23685494, -941.23467666])
V_C_I = np.array([ 61.66341, 62.342903, 67.9311515])
E_14 = np.array([-941.22938469, -941.23583586, -941.23605613])
V_14 = np.array([ 54.65693125, 58.47115725, 60.8626545 ])
P_C_I = np.array([ 2.20068119, 1.33328211, -4.28370285])
P_14 = np.array([ 8.16605135, 7.54737315, 0.3909309 ])
axes[0][0].scatter(V_C_I, E_C_I, marker='^', color='red', label='Calcite I')#, s=100)
axes[0][0].scatter(V_14, E_14, marker='o', color='green', label='Calcite I')#, s=100)
axes[0][0].set_ylim(bottom=-941.238, top=-941.229)
plt.tight_layout()
axes[0][0].ticklabel_format(useOffset=False)
plt.show()
sys.exit()
Everything seems fine:
I have forced the plot to axes[0][0].set_ylim(bottom=-941.238, top=-941.229)
When I try to plot Y2
versus X
for Case 1
, the following code should work: I am basically doing the same as before, but adding the axes[1][0]
plotting instruction:
import numpy as np
import matplotlib.pyplot as plt
import sys
fig, axes = plt.subplots(ncols=4, nrows=3,\
sharex=True, sharey=True,\
subplot_kw=dict(adjustable='box-forced'))
pad = 5
axes[0][0].annotate('Case 1', xy=(0.5, 1), xytext=(0, pad),
xycoords='axes fraction', textcoords='offset points',
size='large', ha='center', va='baseline')
axes[0][1].annotate('Case 2', xy=(0.5, 1), xytext=(0, pad),
xycoords='axes fraction', textcoords='offset points',
size='large', ha='center', va='baseline')
axes[0][2].annotate('Case 3', xy=(0.5, 1), xytext=(0, pad),
xycoords='axes fraction', textcoords='offset points',
size='large', ha='center', va='baseline')
axes[0][3].annotate('Case 4', xy=(0.5, 1), xytext=(0, pad),
xycoords='axes fraction', textcoords='offset points',
size='large', ha='center', va='baseline')
#
axes[0][0].set_ylabel('Y1', fontsize=10)
axes[1][0].set_ylabel('Y2', fontsize=10)
axes[2][0].set_ylabel('Y3', fontsize=10)
E_C_I = np.array([-941.23658347, -941.23685494, -941.23467666])
V_C_I = np.array([ 61.66341, 62.342903, 67.9311515])
E_14 = np.array([-941.22938469, -941.23583586, -941.23605613])
V_14 = np.array([ 54.65693125, 58.47115725, 60.8626545 ])
P_C_I = np.array([ 2.20068119, 1.33328211, -4.28370285])
P_14 = np.array([ 8.16605135, 7.54737315, 0.3909309 ])
axes[0][0].scatter(V_C_I, E_C_I, marker='^', color='red', label='Calcite I')#, s=100)
axes[0][0].scatter(V_14, E_14, marker='o', color='green', label='Calcite I')#, s=100)
axes[0][0].set_ylim(bottom=-941.238, top=-941.229)
axes[1][0].scatter(V_C_I, P_C_I, marker='^', color='red', label='Calcite I')#, s=100)
axes[1][0].scatter(V_14, P_14, marker='o', color='green', label='Calcite I')#, s=100)
axes[1][0].set_ylim(bottom=-4.4, top=8.4)
plt.tight_layout()
axes[0][0].ticklabel_format(useOffset=False)
plt.show()
sys.exit()
The result is that the axes[0][0]
plot has changed its scale, and therefore no data is shown:
I have forced both axes[0][0]
and axes[0][1]
to show the region where indeed there is data:
axes[0][0].set_ylim(bottom=-941.238, top=-941.229)
axes[1][0].set_ylim(bottom=-4.4, top=8.4)
However, no data is shown on the axes[0][0]
plot. Why is this happening?
Update: The difference between sharey='row'
and sharey=True
has been clarified in the excellent @DavidG's answer. However, I have tested the difference between sharex='col'
and sharex=True
and I have noticed that:
fig, axes = plt.subplots(ncols=4, nrows=3,\
sharex=True, sharey='row',\
subplot_kw=dict(adjustable='box-forced'))
produces the following:
However,
fig, axes = plt.subplots(ncols=4, nrows=3,\
sharex='col', sharey='row',\
subplot_kw=dict(adjustable='box-forced'))
kind of leaves some space between the columns, and breaks the adjustable='box-forced'
declaration for the subplots to be squared:
I was wondering why this is happening?