 # text on top just below xticks

I don't think so. I looked at that. Maybe I'm mistaken,

> but seems that in the end, it just places the text at y
> position 0.9 in Axes coordinates. That's just below the
> markers for small subplots, but WAY below the markers for
> tall skinny ones. I want it to place the text at a fixed
> absolute y position of just below the markers. As the
> graph gets taller, that will go from .9 to .95 to .99,
> etc. in Axes coordinates.

> So one approach would be to find the Axes coordinates for
> the lower limit of the tick markers. Any ideas?

This is a bit tricky but doable. The transformation that places the
xticks is a "blend" of the data transform and the axes transform, in
that the x value of the x ticks is a data coord, and the y value is an
axes coord(0 is bottom, 1 is top). The transform module provides a
helper function to build such a beast

from matplotlib.transforms import blend_xy_sep_transform
trans = blend_xy_sep_transform(ax.transData, ax.transAxes)

If you then make a call to text

ax.text(.2,1,'hi mom', transform=trans)

it will be placed at the top of the yaxis at 0.2 on the xaxis.

What you want to do is offset this by a couple of points below the
tick like. To do this, you need to set an offset on the transform,
where the coordinates of the offset are in points. The offset is
always an xy tuple with a transform to transform that tuple into
figure coords. In the case of points, you want to do

scale = fig.dpi/Value(72.) # points -> pixels
point_trans = scale_transform(scale, scale)
trans.set_offset((0,-ticksize-2),point_trans)

Here is a complete example: now when you resize the figure window or
pan/zoom your text will remain 2 points below the ticks...

from matplotlib import rcParams
import matplotlib.numerix as nx
from pylab import figure, show
from matplotlib.transforms import blend_xy_sep_transform, Value, scale_transform

ticksize = rcParams['xtick.major.size']

fig = figure()
x,y = nx.mlab.rand(2,100)
ax.plot(x,y)
locs = nx.arange(0,1.0,0.2)
ax.set_xticks(locs)

trans = blend_xy_sep_transform(ax.transData, ax.transAxes)
scale = fig.dpi/Value(72.) # points -> pixels
point_trans = scale_transform(scale, scale)

# the offset is an xy tup and a transformation instance for that tuple
trans.set_offset((0,-ticksize-2),point_trans)

for loc in locs:
ax.text(loc,1,'%1.1f'%loc, transform=trans, va='top', ha='center')
show()

John,

Thanks, that did it. I don't really need to blend though. What I
need it taken care of by:

#trans = blend_xy_sep_transform(ax.transData, ax.transAxes)
trans = blend_xy_sep_transform(ax.transAxes, ax.transAxes)
scale = fig.dpi/Value(72.) # points -> pixels
point_trans = scale_transform(scale, scale)
trans.set_offset((0,-ticksize-2),point_trans)
ax.text(0.5, 1, "My Title", ha='center', va='top', transform=trans)

It seems a bit silly to call the blend_xy transform for that (since
I'm using transAxes for both x and y), but copy.copy doesn't work, so
there we are.

Thanks again.
-C

···

On 1/11/06, John Hunter <jdhunter@...8...> wrote:

> I don't think so. I looked at that. Maybe I'm mistaken,
> but seems that in the end, it just places the text at y
> position 0.9 in Axes coordinates. That's just below the
> markers for small subplots, but WAY below the markers for
> tall skinny ones. I want it to place the text at a fixed
> absolute y position of just below the markers. As the
> graph gets taller, that will go from .9 to .95 to .99,
> etc. in Axes coordinates.

> So one approach would be to find the Axes coordinates for
> the lower limit of the tick markers. Any ideas?

This is a bit tricky but doable. The transformation that places the
xticks is a "blend" of the data transform and the axes transform, in
that the x value of the x ticks is a data coord, and the y value is an
axes coord(0 is bottom, 1 is top). The transform module provides a
helper function to build such a beast

from matplotlib.transforms import blend_xy_sep_transform
trans = blend_xy_sep_transform(ax.transData, ax.transAxes)

If you then make a call to text

ax.text(.2,1,'hi mom', transform=trans)

it will be placed at the top of the yaxis at 0.2 on the xaxis.

What you want to do is offset this by a couple of points below the
tick like. To do this, you need to set an offset on the transform,
where the coordinates of the offset are in points. The offset is
always an xy tuple with a transform to transform that tuple into
figure coords. In the case of points, you want to do

scale = fig.dpi/Value(72.) # points -> pixels
point_trans = scale_transform(scale, scale)
trans.set_offset((0,-ticksize-2),point_trans)

Here is a complete example: now when you resize the figure window or
pan/zoom your text will remain 2 points below the ticks...

from matplotlib import rcParams
import matplotlib.numerix as nx
from pylab import figure, show
from matplotlib.transforms import blend_xy_sep_transform, Value, scale_transform

ticksize = rcParams['xtick.major.size']

fig = figure()
x,y = nx.mlab.rand(2,100)
ax.plot(x,y)
locs = nx.arange(0,1.0,0.2)
ax.set_xticks(locs)

trans = blend_xy_sep_transform(ax.transData, ax.transAxes)
scale = fig.dpi/Value(72.) # points -> pixels
point_trans = scale_transform(scale, scale)

# the offset is an xy tup and a transformation instance for that tuple
trans.set_offset((0,-ticksize-2),point_trans)

for loc in locs:
ax.text(loc,1,'%1.1f'%loc, transform=trans, va='top', ha='center')
show()

--
Charles R. Twardy