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 |