Update: If you find yourself here with a similar problem, I found a solution that worked for me (see my response below) here; Adjust y-axis in Seaborn multiplot
The best is the enemy of the good...
I wrote a for loop to create a figure with two rows and four columns. The xaxis is shared by column (sharex='col'
), the yaxis by row (sharey='row'
). And it worked great...until I tried to use this inside my loop to force the yaxis range of the first row:
axes[0, i].set(yticks=range(0,70,10))
Now when I run the code, only the subplot axes[0,3]
(i.e. the final subplot in this row) respects the axes[0, i].set(yticks=range(0,70,10))
line of code. The other three subplots to the left of it on the same row keep their default ytick values derived from the data (see image below).
This means that, despite the fact that sharey='row'
, axes[0,0]
, axes[0,1]
, and axes[0,2]
share a yaxis that is not shared by axes[0,3]
.
If I set sharey=False
, then all the subplots in the row respect the axes[0, i].set(yticks=range(0,70,10))
code, but not according to the same vertical scale, not to mention that sharey=False
also messes up my second row of subplots.
Does anyone understand why axes[0, i].set(yticks=range(0,70,10))
is seemingly being applied only once in the loop, instead of four times? Thank you.
Edit: I can't provide data, but here's basically what my full code looks like:
fig, axes = plt.subplots(2, 4, figsize=(20, 12), sharex=True, sharey='row')
for i in range(4):
sns.lineplot(ax = axes[0, i], x=x, y=y,
data=data)
sns.despine()
axes[0, i].grid(True, alpha=0.2)
axes[0, i].tick_params(axis='both', which='major', labelsize=13)
axes[0, i].axhline(y=50, color='k', dashes=(2, 1), zorder=0)
axes[0, i].set(yticks=range(0,70,10))
axes[0, 0].set_ylabel('y axis row 0', fontsize=14)
for i in range(4):
sns.lineplot(ax = axes[1, i], x=x1, y=y1,
data=data1)
sns.despine()
axes[1, i].grid(True, alpha=0.2)
axes[1, i].set(xticks=[0, 1, 2, 3, 4])
axes[1, i].axhline(y=0, color='red', dashes=(2, 1), zorder=0)
axes[1, i].tick_params(axis='both', which='major', labelsize=13)
axes[1, 0].set_ylabel('y axis row 1', fontsize=14)
And here's what I'm getting out. See that the top right subplot, axes[0,3]
, has the yaxis the way I want, but not the others on the same row:
Edit: I found a solution that worked for me in this solution here: https://stackoverflow.com/a/57101557/13917918
By adding g = sns.lineplot...
and then placing a call to g.axes.set_ylim(0,70)
inside the loop, I got the desired result. Example of working code:
fig, axes = plt.subplots(2, 4, figsize=(20, 12), sharex=True, sharey='row')
for i in range(4):
g = sns.lineplot(ax = axes[0, i], x=x, y=y,
data=data)
g.axes.set_ylim(0,70)
axes[0, i].grid(True, alpha=0.2)
axes[0, i].tick_params(axis='both', which='major', labelsize=13)
axes[0, i].axhline(y=50, color='k', dashes=(2, 1), zorder=0)
axes[0, 0].set_ylabel('y0', fontsize=14)
for i in range(4):
sns.lineplot(ax = axes[1, i], x=x1, y=y1,
data=data1)
sns.despine()
axes[1, i].grid(True, alpha=0.2)
axes[1, i].set(xticks=[0, 1, 2, 3, 4])
axes[1, i].axhline(y=0, color='red', dashes=(2, 1), zorder=0)
axes[1, i].tick_params(axis='both', which='major', labelsize=13)
axes[1, 0].set_ylabel('y1', fontsize=14)