Reputation: 4958
I'm wondering how I might set the Y label in the following plot all inline with one another. Currently they are misaligned since the Y values are not of equal space.
Upvotes: 2
Views: 650
Reputation: 69116
You can do this more elegantly with ax.yaxis.set_label_coords
, using a constant value for the x coordinate, as shown here. For your example:
import matplotlib.pyplot as plt
labels = ['$P_{EUC}[mm]$', '$P_z[mm]$', '$P_Y[mm]$', '$P_X[mm]$']
fig,axs=plt.subplots(4,1,sharex=True)
axs[0].set_ylim(-1000,0)
axs[1].set_ylim(-0.0010,0.0020)
axs[2].set_ylim(0,5)
axs[3].set_ylim(0,20)
[axs[i].set_ylabel(labels[i]) for i in range(4)]
labelx = -0.1 # Change this to suit your needs
[axs[i].yaxis.set_label_coords(labelx,0.5) for i in range(4)]
fig.savefig('labelx.png')
Upvotes: 2
Reputation: 284602
In this case, it's probably easier to not use the ylabel
at all. Instead, use annotate
to place the text at a constant offset from the left side of the axes.
As an example of your problem:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=4, sharex=True)
yranges = [(-1000, 100), (-0.001, 0.002), (0, 5), (0, 20)]
labels = ['$P_{EUC}[mm]$', '$P_z[mm]$', '$P_Y[mm]$', '$P_X[mm]$']
for ax, yrange, label in zip(axes, yranges, labels):
ax.set(ylim=yrange, ylabel=label)
plt.show()
To solve this, it's easiest to use annotate
. The trick is to position the text at y=0.5
in axes coordinates, and then 5 points from the left hand edge of the figure in the x-direction. The syntax is a bit verbose, but is relatively easy to read. The key is in the xycoords
and textcoords
kwargs that control how xy
and xytext
are interpreted:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=4, sharex=True)
yranges = [(-1000, 100), (-0.001, 0.002), (0, 5), (0, 20)]
labels = ['$P_{EUC}[mm]$', '$P_z[mm]$', '$P_Y[mm]$', '$P_X[mm]$']
for ax, yrange, label in zip(axes, yranges, labels):
ax.set(ylim=yrange)
ax.annotate(label, xy=(0, 0.5), xytext=(5, 0), rotation=90,
xycoords=('figure fraction', 'axes fraction'),
textcoords='offset points', va='center', ha='left')
plt.show()
Upvotes: 2
Reputation: 5373
You can offset x and y labels using the set_ylabel method on the AxesSubplots. http://matplotlib.org/api/axes_api.html?highlight=y%20label#matplotlib.axes.Axes.set_ylabel
You can also format the y tick mark labels. http://matplotlib.org/api/axes_api.html?highlight=y%20label#matplotlib.axes.Axes.set_yticklabels
When working with matplotlib text objects, you can use the argument transform=ax.transAxes
to use Figure
coordinates instead of Axes
coordinates if you want to loop through the subfigures.
But I think what you're looking for is just to offset them. When the docs are sparse, use dir()
to poke through the namespace.
fig, ax = plt.subplots(1, 1)
dir(ax)
includes yaxis
.
dir(ax.yaxis)
includes get_label
.
dir(ax.yaxis.get_label())
includes set_x
.
help(ax.yaxis.get_label().set_x
says:
set_x(self, x) method of matplotlib.text.Text instance
Set the *x* position of the text
ACCEPTS: float
Upvotes: 0