From: Fernando P. <Fer...@co...> - 2005-02-09 19:41:22
|
Hi all, I am having a bit of a problem with the order things get drawn. I looked at the zorder example and the docs, but I can't seem to find a solution. Here's an illustration: http://amath.colorado.edu/faculty/fperez/tmp/zorder_prob.png The red wiggly line is drawn first, by a loglog() call, and then the green one is an axhline() call. However, the green line ends up below the red one. It turns out that in cases where the range of the red stuff is above the green cutoff, this causes the green line to be totally obscured. And for my plots, it's important that the green line is clearly visible always. My naive expectation was that whatever was called last on the plot would end up on top, but that doesn't seem to be the case. I did a few experiments: x=frange(0,2*pi,npts=100) figure() plot(x,sin(x),x,cos(x),linewidth=10) plot(x,sin(2*x),linewidth=10) axhline(0,linewidth=10) And I can't really figure out what determines the zorder of all the line objects. Is there a way to control this? Would it make sense to make the default behavior something more like what hand-drawing would cause? I mean: you draw on the canvas as if it were paper, and newly drawn lines appear on top of older ones. Maybe there's a good reason for the current design, and I'm just missing the proper incantation. I'd be very grateful for a pointer in the right direction. Cheers, f |
From: John H. <jdh...@ac...> - 2005-02-09 20:00:04
|
>>>>> "Fernando" == Fernando Perez <Fer...@co...> writes: Fernando> Hi all, I am having a bit of a problem with the order Fernando> things get drawn. I looked at the zorder example and Fernando> the docs, but I can't seem to find a solution. Here's Fernando> an illustration: Fernando> http://amath.colorado.edu/faculty/fperez/tmp/zorder_prob.png Fernando> The red wiggly line is drawn first, by a loglog() call, Fernando> and then the green one is an axhline() call. However, Fernando> the green line ends up below the red one. It turns out Fernando> that in cases where the range of the red stuff is above Fernando> the green cutoff, this causes the green line to be Fernando> totally obscured. And for my plots, it's important that Fernando> the green line is clearly visible always. Fernando> My naive expectation was that whatever was called last Fernando> on the plot would end up on top, but that doesn't seem Fernando> to be the case. I did a few experiments: Fernando> x=frange(0,2*pi,npts=100) figure() Fernando> plot(x,sin(x),x,cos(x),linewidth=10) Fernando> plot(x,sin(2*x),linewidth=10) axhline(0,linewidth=10) Hmm, seems to work for me -- you didn't specify the colors in your example which makes it hard to test, so I'll add them from pylab import * x=frange(0,2*pi,npts=100) figure() plot(x,sin(x),x,cos(x),linewidth=10, color='red') plot(x,sin(2*x),linewidth=10, color='green') axhline(0,linewidth=10, color='blue') show() with results at http://matplotlib.sf.net/jdh.png Fernando> And I can't really figure out what determines the zorder Fernando> of all the line objects. Well the zorder kwarg is your friend -- did you see examples/zorder_demo.py ? Eg plot(x,y, zorder=100) # I'm on top! I think I have an idea of what may be causing the plot order problem you are experiencing From axes.py draw method artists = [] artists.extend(self.collections) artists.extend(self.patches) artists.extend(self.lines) artists.extend(self.texts) dsu = [ (a.zorder, a) for a in artists] dsu.sort() for zorder, a in dsu: a.draw(renderer) Now, if I recall correctly, python sort doesn't guarantee preserving order for equal element. Since the order in the respective list (patches, lines, etc) *is* determined by the order of the plot commands, we might be better off with dsu = [ (a.zorder, i, a) for i, a in enumerate(artists)] dsu.sort() for zorder, i, a in dsu: a.draw(renderer) to guarantee relative order for artists with the same zorder. Or is sort relative order preserving for equal elements? JDH |
From: Fernando P. <Fer...@co...> - 2005-02-09 21:48:04
|
John Hunter wrote: > Hmm, seems to work for me -- you didn't specify the colors in your > example which makes it hard to test, so I'll add them Weird. I ran this a ton of times, and in _most_ cases I get your same results. And yet a _few_ times, and only when I pasted the code in an interactive window, the horizontal line ends below the sine/cosine plots. Very, very strange. > Well the zorder kwarg is your friend -- did you see > examples/zorder_demo.py ? Eg > > plot(x,y, zorder=100) # I'm on top! I did read it, but I guess I misunderstood the docstring on top. I understood it as meaning that you could only reorder classes of objects relative to one another (lines, text, patches), but not individual lines within the class of all lines. > Now, if I recall correctly, python sort doesn't guarantee preserving > order for equal element. Since the order in the respective list > (patches, lines, etc) *is* determined by the order of the plot > commands, we might be better off with > > dsu = [ (a.zorder, i, a) for i, a in enumerate(artists)] > dsu.sort() > > for zorder, i, a in dsu: > a.draw(renderer) > > to guarantee relative order for artists with the same zorder. > > Or is sort relative order preserving for equal elements? Well, the funny thing about my sometimes-odd results, is that in python 2.3, list.sort _is_ stable: http://py-stablesort.sourceforge.net/doc/2002_07_28_pythonowns_archive.html http://mail.python.org/pipermail/python-list/2003-April/160326.html So I'm not quite sure why I get odd results in a few cases. And I can't seem to find a reliable way to repeat the behavior. But thanks for the clarification on the zorder argument, that's enough for me to get the behavior I need. I'll update the zorder_demo example with a more explicit docstring so others don't fall into the same confusion. Cheers, f |
From: John H. <jdh...@ac...> - 2005-02-09 22:55:10
|
>>>>> "Fernando" == Fernando Perez <Fer...@co...> writes: Fernando> Well, the funny thing about my sometimes-odd results, is Fernando> that in python 2.3, list.sort _is_ stable: Fernando> http://py-stablesort.sourceforge.net/doc/2002_07_28_pythonowns_archive.html Fernando> http://mail.python.org/pipermail/python-list/2003-April/160326.html Fernando> So I'm not quite sure why I get odd results in a few Fernando> cases. And I can't seem to find a reliable way to Fernando> repeat the behavior. Hmm, I hesitate to say this, but I wonder if it's a bug in the stable sort. I also see the behavior you describe in ipython -- intermittently the order is wrong. But when I add the extra ind to the axes dsu sort, I never get it. Changes in CVS. Make sure you have revision - CHANGELOG 1.270 Fernando> But thanks for the clarification on the zorder argument, Fernando> that's enough for me to get the behavior I need. Fernando> I'll update the zorder_demo example with a more explicit Fernando> docstring so others don't fall into the same confusion. Thanks. JDH |