Pixel placement of text

I think that what you want to do requires something like the

    > mechanism in QuiverKey: a derived artist with a draw method
    > that figures out at draw time where to put the text; I don't
    > think there is any other way to handle zooming while keeping
    > the screen separation from a data point fixed.

You can do this using offsets -- see
matplotlib.axis.XTick._get_text1. This is how tick labeling is done
(a point offset from an x location in data coords and a y location in
axis coords). Here is an example -- you have to copy the default data
transform so that the offset doesn't affect the figure data

from matplotlib.transforms import Value, translation_transform,blend_xy_sep_transform
from pylab import figure, show

fig = figure()
ax = fig.add_subplot(111)
points = 7
pad = fig.dpi*Value(points/72.0)
# poor man's copy
trans = blend_xy_sep_transform(ax.transData, ax.transData)

# to the left and above
offset = translation_transform(Value(-1)*pad, pad)
trans.set_offset( (0,0), offset)

ax.plot([1,2,3])

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

show()

Attached is a simple example that illustrates the method. What threw me off last night is that the copy_bbox_transform() function was not doing what I expected. I don't know yet whether this is because of a bug or a misunderstanding on my part, but in any case, the example provides an alternative. (It is not valid for any bbox transform, but I think it will be fine in normal use cases.) The basic method can be used on any artist by calling set_offset on that artist's transform. Once again, John's transform module works its magic!

I will make a more complete example and include it in the examples subdirectory of mpl. This is really great functionality that needs to be made more readily accessible.

Eric

John Hunter wrote:

transoffset.py (848 Bytes)

···

"Eric" == Eric Firing <efiring@...202...> writes:

    > I think that what you want to do requires something like the
    > mechanism in QuiverKey: a derived artist with a draw method
    > that figures out at draw time where to put the text; I don't
    > think there is any other way to handle zooming while keeping
    > the screen separation from a data point fixed.

You can do this using offsets -- see
matplotlib.axis.XTick._get_text1. This is how tick labeling is done
(a point offset from an x location in data coords and a y location in
axis coords). Here is an example -- you have to copy the default data
transform so that the offset doesn't affect the figure data

from matplotlib.transforms import Value, translation_transform,blend_xy_sep_transform
from pylab import figure, show

fig = figure()
ax = fig.add_subplot(111)
points = 7
pad = fig.dpi*Value(points/72.0)
# poor man's copy
trans = blend_xy_sep_transform(ax.transData, ax.transData)

# to the left and above
offset = translation_transform(Value(-1)*pad, pad)
trans.set_offset( (0,0), offset)

ax.plot([1,2,3])

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

show()