Pixel placement of text

"Bill Baxter" <wbaxter@...287...> writes:

I want to draw some labels with plot.text() and have them appear a
given number of pixels (or mm, or points) to above and to the right of
the data points they are describing. Is there some way to specify a
screen offset from a point in graph coordinates?

Here's what I came up with. Perhaps the matplotlib gurus know a
simpler way... (One way to simplify this would be to add a new
"offset" Func in _transforms.cxx, so the user could just copy the
transData transform and call set_funcx and set_funcy with suitable
offset functions.)

pxoff.py (763 Bytes)

Hey that's great. Thanks Jouni. There may be a better way, but this
is at least a lot easier to figure out than the code in QuiverKey!

You can even throw all the magic into one function like this:

def const_offset(x,y):
   ax = gca()
   ll1 = ax.transData.get_bbox1().ll()
   ur1 = ax.transData.get_bbox1().ur()
   ll2 = ax.transData.get_bbox2().ll()
   ur2 = ax.transData.get_bbox2().ur()

   scale_x = (ur2.x()-ll2.x())/(ur1.x()-ll1.x())
   scale_y = (ur2.y()-ll2.y())/(ur1.y()-ll1.y())

   offset = Point(Value(x), Value(y))
   trans = Affine(scale_x, zero(), zero(), scale_y,
                  ll2.x()-scale_x*ll1.x() + offset.x(),
                  ll2.y()-scale_y*ll1.y() + offset.y())
   return trans

And then just add a transform=const_offset(x,y) parameter wherever
you want one.
Great. And it works for things besides text too.

···

--------------------
#!/usr/bin/env python

import matplotlib
from matplotlib.transforms import Value, zero, Affine, Point
from pylab import figure, show, gca

def const_offset(x,y):
   ax = gca()
   ll1 = ax.transData.get_bbox1().ll()
   ur1 = ax.transData.get_bbox1().ur()
   ll2 = ax.transData.get_bbox2().ll()
   ur2 = ax.transData.get_bbox2().ur()

   scale_x = (ur2.x()-ll2.x())/(ur1.x()-ll1.x())
   scale_y = (ur2.y()-ll2.y())/(ur1.y()-ll1.y())

   offset = Point(Value(x), Value(y))
   trans = Affine(scale_x, zero(), zero(), scale_y,
                  ll2.x()-scale_x*ll1.x() + offset.x(),
                  ll2.y()-scale_y*ll1.y() + offset.y())
   return trans

x = (3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3)
y = (2,7,1,8,2,8,1,8,2,8,4,5,9,0,4,5)

fig=figure()
ax=fig.add_subplot(111)
ax.plot(x,y,'.')

for a,b in zip(x,y):
   ax.text(a, b, '(%d,%d)'%(a,b), transform=const_offset(20,0))

ax.plot(x,y, 'gv',transform=const_offset(0,-10))
ax.plot(x,y, 'm^',transform=const_offset(0, 10))

show()