|
From: John H. <jdh...@ac...> - 2004-03-03 17:57:45
|
>>>>> "Phil" == Phil Erickson <pj...@ha...> writes:
Phil> Hello John, I have run into the following minor matplotlib
Phil> bug. Using the sample code below, the y axis label and tick
Phil> marks in the second subplot seem not to be in the right
Phil> places. Also on that second subplot, the first legend is
Phil> missing when the window is initially drawn, but gets redrawn
Phil> correctly if I use the x axis interactive scrolling buttons.
Hi Phil,
Wow, that was a subtle one. Thanks very much for a detailed
description, screenshot and demo code. You can distill the essence of
the bug in this script
from matplotlib.matlab import *
subplot(211)
plot([1,2,3])
ylabel('Test me')
subplot(212)
plot([1,2,3])
ylabel('Test me')
show()
The key observation is that this script exposes the bug, but
examples/subplot_demo.py does not. I found that if I commented out
the first ylabel the bug also disappeared. This led me to the
solution.
I cache font instances in many of the backends since font creation and
drawing can be expensive, particularly on the GTK backend for vertical
text where I have to do the rotation by hand, pixel-by-pixel in
python. In the cache I map text properties to font instances in a
dictionary. As one of the properties, I was using the x, and y coords
of the text in *user* rather than *display* coords, so the second
ylabel was using the cached information of the first. In the case of
the ylabels, the user coords are relative to their respective axes,
and so are identical for identical labels.
The same explanation applies to the legend code because the legends
had duplicate text.
A simple fix. In matplotlib.text.py, on or around line 118 replace
get_prop_tup with
def get_prop_tup(self):
"""
Return a hashable tuple of properties
Not intended to be human readable, but useful for backends who
want to cache derived information about text (eg layouts) and
need to know if the text has changed
"""
x, y = self.get_xy_display()
return (x, y, self._text, self._color,
self._verticalalignment, self._horizontalalignment,
self._fontname, self._fontsize, self._fontweight,
self._fontangle, self._rotation, self.dpi.get())
The key is to use the display coords for the cache value.
Thanks again,
JDH
|