Here are my questions:
1. I have extended the Line2D class as I am using _nolegend_ in the label.
I still wanted to differentiate between lines using something called id. Is
there a better way of doing it with built-in attributes?
Nothing built into matplotlib, but python has an "id" function and the
line objects are hashable, so you probably don't need anything else.
2. I can remove the line but somehow the text added to the axes does not
respond to pick events. Anybody has any thoughts?
It turns out text picking was broken in svn. When I looked at the
implementation, I saw
try:
l,b,w,h = self.get_window_extent().get_bounds()
except:
# TODO: why does this error occur
#print str(self),"error looking at get_window_extent"
return False,{}
so apparently some developer saw this was broken, hid it with a
blanket except that was silent, and forgot to get back to the TODO.
bbox.get_bounds did not survive the transform refactor, and is now
called bbox.bounds. This could of been me, thinking I would fix it
and then forgot about it, but I certainly hope not. Note to
developers: never catch all exceptions with a blanket except that
doesn't at least warn. This is fixed in svn so text picking is
working again.
3. The neat thing would be to add the text into the CustomLine class so
line's label is contained in the class. Not sure how I can do it because
text needs an axis and axis is nor associated with Line2D until you add the
line to axis...
4. How can I add a constant offset like (2 pixels right, 2 pixels up) at the
right end of the line for its text label.
This is possible, but is a little harder than it should be because to
do it elegantly you need to override a lot of methods. If we had a
proper containment API, it would be a lot easier and this is probably
something worth doing. I wrote up an example (added it to
examples/api/line_with_text.py in svn).
In general, I think it would be nice to add support for all artists
(lines, patches, whatever) to display their label. We would need to
think a little bit about the API for placing the label (eg if every
artist provides their extent, one could place the label at "upper
right" with a certain offset.
Here is the example:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.lines as lines
import matplotlib.transforms as mtransforms
import matplotlib.text as mtext
class MyLine(lines.Line2D):
def __init__(self, *args, **kwargs):
# we'll update the position when the line data is set
self.text = mtext.Text(0, 0, '')
lines.Line2D.__init__(self, *args, **kwargs)
# we can't access the label attr until *after* the line is
# inited
self.text.set_text(self.get_label())
def set_figure(self, figure):
self.text.set_figure(figure)
lines.Line2D.set_figure(self, figure)
def set_axes(self, axes):
self.text.set_axes(axes)
lines.Line2D.set_axes(self, axes)
def set_transform(self, transform):
# 2 pixel offset
texttrans = transform + mtransforms.Affine2D().translate(2, 2)
self.text.set_transform(texttrans)
lines.Line2D.set_transform(self, transform)
def set_data(self, x, y):
if len(x):
self.text.set_position((x[-1], y[-1]))
lines.Line2D.set_data(self, x, y)
def draw(self, renderer):
# draw my label at the end of the line with 2 pixel offset
lines.Line2D.draw(self, renderer)
self.text.draw(renderer)
fig = plt.figure()
ax = fig.add_subplot(111)
x, y = np.random.rand(2, 20)
line = MyLine(x, y, mfc='red', ms=12, label='line label')
#line.text.set_text('line label')
line.text.set_color('red')
line.text.set_fontsize(16)
ax.add_line(line)
plt.show()
···
On Wed, Jul 2, 2008 at 7:13 PM, Nihat <ngdev38@...287...> wrote: