transforms bug: axhline with log y scale

Mike (or other transforms afficionados),

The thread "[Matplotlib-users] Bug saving semilogy plots with a axvline" started by jsilva@...250... pointed to a bug that appears to be deep in the transforms code. My head is spinning. The problem seems to be related to the propagation of the _invalid attribute in transforms, in the case of a mixed data/axes transform such as ashline uses. The following one-line change in TransformNode, second line from the bottom, works:

     def invalidate(self):
         """
         Invalidate this :class:`TransformNode` and all of its
         ancestors. Should be called any time the transform changes.
         """
         # If we are an affine transform being changed, we can set the
         # flag to INVALID_AFFINE_ONLY
         value = (self.is_affine) and self.INVALID_AFFINE or self.INVALID

         # Shortcut: If self is already invalid, that means its parents
         # are as well, so we don't need to do anything.
         if self._invalid == value:
             return

         if not len(self._parents):
             self._invalid = value
             return

         # Invalidate all ancestors of self using pseudo-recursion.
         parent = None
         stack = [self]
         while len(stack):
             root = stack.pop()
             # Stop at subtrees that have already been invalidated
             if root._invalid != value or root.pass_through:
                 root._invalid = self.INVALID # value <===========
                 stack.extend(root._parents.keys())

Now, I know this is the wrong solution, because it defeats all the cleverness with the _invalid values; but perhaps it will save you a few minutes in finding the right solution.

To reproduce the problem, do this in ipython -pylab:

axhline(5)
yscale('log')
ylim(0.5,30)

Eric

Mike,

This is a gentle check--I suspect my original message, below, may have slipped under the radar.

Eric

Eric Firing wrote:

···

Mike (or other transforms afficionados),

The thread "[Matplotlib-users] Bug saving semilogy plots with a axvline" started by jsilva@...250... pointed to a bug that appears to be deep in the transforms code. My head is spinning. The problem seems to be related to the propagation of the _invalid attribute in transforms, in the case of a mixed data/axes transform such as ashline uses. The following one-line change in TransformNode, second line from the bottom, works:

     def invalidate(self):
         """
         Invalidate this :class:`TransformNode` and all of its
         ancestors. Should be called any time the transform changes.
         """
         # If we are an affine transform being changed, we can set the
         # flag to INVALID_AFFINE_ONLY
         value = (self.is_affine) and self.INVALID_AFFINE or self.INVALID

         # Shortcut: If self is already invalid, that means its parents
         # are as well, so we don't need to do anything.
         if self._invalid == value:
             return

         if not len(self._parents):
             self._invalid = value
             return

         # Invalidate all ancestors of self using pseudo-recursion.
         parent = None
         stack = [self]
         while len(stack):
             root = stack.pop()
             # Stop at subtrees that have already been invalidated
             if root._invalid != value or root.pass_through:
                 root._invalid = self.INVALID # value <===========
                 stack.extend(root._parents.keys())

Now, I know this is the wrong solution, because it defeats all the cleverness with the _invalid values; but perhaps it will save you a few minutes in finding the right solution.

To reproduce the problem, do this in ipython -pylab:

axhline(5)
yscale('log')
ylim(0.5,30)

Eric

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Thanks for the reminder. It wasn't propagating the "non-affine" invalidation correctly. I think I have a fix in r6465, but please let me know if you see anything else funny.

Cheers,
Mike

Eric Firing wrote:

···

Mike,

This is a gentle check--I suspect my original message, below, may have slipped under the radar.

Eric

Eric Firing wrote:

Mike (or other transforms afficionados),

The thread "[Matplotlib-users] Bug saving semilogy plots with a axvline" started by jsilva@...250... pointed to a bug that appears to be deep in the transforms code. My head is spinning. The problem seems to be related to the propagation of the _invalid attribute in transforms, in the case of a mixed data/axes transform such as ashline uses. The following one-line change in TransformNode, second line from the bottom, works:

     def invalidate(self):
         """
         Invalidate this :class:`TransformNode` and all of its
         ancestors. Should be called any time the transform changes.
         """
         # If we are an affine transform being changed, we can set the
         # flag to INVALID_AFFINE_ONLY
         value = (self.is_affine) and self.INVALID_AFFINE or self.INVALID

         # Shortcut: If self is already invalid, that means its parents
         # are as well, so we don't need to do anything.
         if self._invalid == value:
             return

         if not len(self._parents):
             self._invalid = value
             return

         # Invalidate all ancestors of self using pseudo-recursion.
         parent = None
         stack = [self]
         while len(stack):
             root = stack.pop()
             # Stop at subtrees that have already been invalidated
             if root._invalid != value or root.pass_through:
                 root._invalid = self.INVALID # value <===========
                 stack.extend(root._parents.keys())

Now, I know this is the wrong solution, because it defeats all the cleverness with the _invalid values; but perhaps it will save you a few minutes in finding the right solution.

To reproduce the problem, do this in ipython -pylab:

axhline(5)
yscale('log')
ylim(0.5,30)

Eric

-------------------------------------------------------------------------

This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

--
Michael Droettboom
Science Software Branch
Operations and Engineering Division
Space Telescope Science Institute
Operated by AURA for NASA

Michael Droettboom wrote:

Thanks for the reminder. It wasn't propagating the "non-affine" invalidation correctly. I think I have a fix in r6465, but please let me know if you see anything else funny.

Cheers,
Mike

Mike,

It looks like that helps, fixing the window resize behavior, but zooming and panning still do not work in the original example given by João Silva:

import matplotlib.pyplot as pl
import numpy as np

x = np.linspace(0.0,1.0,100)

pl.semilogy(x,x**2)
pl.axvline(x=0.5,ls='--',color='k')
pl.show()

Eric

Hmm... works fine for me here, both with the zoom/pan tool and zoom to rect. Can you describe a particular action that isn't working? I'm at a loss otherwise...

Mike

Eric Firing wrote:

···

Michael Droettboom wrote:

Thanks for the reminder. It wasn't propagating the "non-affine" invalidation correctly. I think I have a fix in r6465, but please let me know if you see anything else funny.

Cheers,
Mike

Mike,

It looks like that helps, fixing the window resize behavior, but zooming and panning still do not work in the original example given by Jo�o Silva:

import matplotlib.pyplot as pl
import numpy as np

x = np.linspace(0.0,1.0,100)

pl.semilogy(x,x**2)
pl.axvline(x=0.5,ls='--',color='k')
pl.show()

Eric

--
Michael Droettboom
Science Software Branch
Operations and Engineering Division
Space Telescope Science Institute
Operated by AURA for NASA

Michael Droettboom wrote:

Hmm... works fine for me here, both with the zoom/pan tool and zoom to rect. Can you describe a particular action that isn't working? I'm at a loss otherwise...

Mike,

When I run João's commands in ipython -pylab and click the pan/zoom button, panning or zooming moves the plotted curve, but the axvline stays in the middle of the picture instead of moving with the x=0.5 point. Same with zoom-to-rect: the axvline stays in the middle of the window, not at x=0.5.

Eric

···

Mike

Eric Firing wrote:

Michael Droettboom wrote:

Thanks for the reminder. It wasn't propagating the "non-affine" invalidation correctly. I think I have a fix in r6465, but please let me know if you see anything else funny.

Cheers,
Mike

Mike,

It looks like that helps, fixing the window resize behavior, but zooming and panning still do not work in the original example given by João Silva:

import matplotlib.pyplot as pl
import numpy as np

x = np.linspace(0.0,1.0,100)

pl.semilogy(x,x**2)
pl.axvline(x=0.5,ls='--',color='k')
pl.show()

Eric

Sorry -- I neglected to commit some changes. (Playing around with bzr and still getting used to it, I guess.)

Mike

Eric Firing wrote:

···

Michael Droettboom wrote:

Hmm... works fine for me here, both with the zoom/pan tool and zoom to rect. Can you describe a particular action that isn't working? I'm at a loss otherwise...

Mike,

When I run Jo�o's commands in ipython -pylab and click the pan/zoom button, panning or zooming moves the plotted curve, but the axvline stays in the middle of the picture instead of moving with the x=0.5 point. Same with zoom-to-rect: the axvline stays in the middle of the window, not at x=0.5.

Eric

Mike

Eric Firing wrote:

Michael Droettboom wrote:

Thanks for the reminder. It wasn't propagating the "non-affine" invalidation correctly. I think I have a fix in r6465, but please let me know if you see anything else funny.

Cheers,
Mike

Mike,

It looks like that helps, fixing the window resize behavior, but zooming and panning still do not work in the original example given by Jo�o Silva:

import matplotlib.pyplot as pl
import numpy as np

x = np.linspace(0.0,1.0,100)

pl.semilogy(x,x**2)
pl.axvline(x=0.5,ls='--',color='k')
pl.show()

Eric

--
Michael Droettboom
Science Software Branch
Operations and Engineering Division
Space Telescope Science Institute
Operated by AURA for NASA

Michael Droettboom wrote:

Sorry -- I neglected to commit some changes. (Playing around with bzr and still getting used to it, I guess.)

Very good, thank you!

OT: I'm glad you are taking a look at bzr; personally, I chose hg quite some time ago (when bzr was not mature enough to use), and I have no regrets. It is very small, quick, and uncluttered--a beautiful piece of work. (The code base is *much* smaller than bzr--I like that.) The one area in which hg is a bit behind now is svn interoperability,
http://www.selenic.com/mercurial/wiki/index.cgi/WorkingWithSubversion,
which doesn't matter at all for the uses to which I put it. Possibly it will catch up soon: http://www.selenic.com/mercurial/wiki/index.cgi/HgSubversion
http://blog.red-bean.com/sussman/?p=116

Eric

···

Mike

Eric Firing wrote:

Michael Droettboom wrote:

Hmm... works fine for me here, both with the zoom/pan tool and zoom to rect. Can you describe a particular action that isn't working? I'm at a loss otherwise...

Mike,

When I run João's commands in ipython -pylab and click the pan/zoom button, panning or zooming moves the plotted curve, but the axvline stays in the middle of the picture instead of moving with the x=0.5 point. Same with zoom-to-rect: the axvline stays in the middle of the window, not at x=0.5.

Eric

Mike

Eric Firing wrote:

Michael Droettboom wrote:

Thanks for the reminder. It wasn't propagating the "non-affine" invalidation correctly. I think I have a fix in r6465, but please let me know if you see anything else funny.

Cheers,
Mike

Mike,

It looks like that helps, fixing the window resize behavior, but zooming and panning still do not work in the original example given by João Silva:

import matplotlib.pyplot as pl
import numpy as np

x = np.linspace(0.0,1.0,100)

pl.semilogy(x,x**2)
pl.axvline(x=0.5,ls='--',color='k')
pl.show()

Eric

Eric Firing wrote:

Michael Droettboom wrote:

Sorry -- I neglected to commit some changes. (Playing around with bzr and still getting used to it, I guess.)

Very good, thank you!

Phew! For a minute there I thought I was going crazy...

OT: I'm glad you are taking a look at bzr; personally, I chose hg quite some time ago (when bzr was not mature enough to use), and I have no regrets. It is very small, quick, and uncluttered--a beautiful piece of work. (The code base is *much* smaller than bzr--I like that.) The one area in which hg is a bit behind now is svn interoperability,
http://www.selenic.com/mercurial/wiki/index.cgi/WorkingWithSubversion,
which doesn't matter at all for the uses to which I put it. Possibly it will catch up soon: http://www.selenic.com/mercurial/wiki/index.cgi/HgSubversion
http://blog.red-bean.com/sussman/?p=116

Yeah -- didn't mean to start another thread about distributed version control -- I'm just playing with the stuff. But that was my assessment, too. Couldn't figure out how to use hg with a svn-based project (matplotlib) -- bzr was easier but still taking some getting used to. git has related features too I might look at.

Mike

···

--
Michael Droettboom
Science Software Branch
Operations and Engineering Division
Space Telescope Science Institute
Operated by AURA for NASA