Hi,

I commited a fixto the axis contains methods, and now have working scroll
wheel zooming code.  I still need to use transforms properly before it can
go into matplotlib, so for now I provide it only for demonstration
purposes.

        - Paul

import math
import matplotlib
#matplotlib.use('WxAgg')
#matplotlib.use('TkAgg')
#matplotlib.use('GtkAgg')
import pylab
import matplotlib.colors as colors

def _rescale(lo,hi,step,pt=None,bal=None,scale='linear'):
    """
    Rescale (lo,hi) by step, returning the new (lo,hi)
    The scaling is centered on pt, with positive values of step
    driving lo/hi away from pt and negative values pulling them in.
    If bal is given instead of point, it is already in [0,1] coordinates.

    This is a helper function for step-based zooming.
    """
    # Convert values into the correct scale for a linear transformation
    # TODO: use proper scale transformers
    if scale=='log':
        lo,hi = math.log10(lo),math.log10(hi)
        if pt is not None: pt = math.log10(pt)

    # Compute delta from axis range * %, or 1-% if percent is negative
    if step > 0:
        delta = float(hi-lo)*step/100
    else:
        delta = float(hi-lo)*step/(100-step)

    # Add scale factor proportionally to the lo and hi values, preserving the
    # point under the mouse
    if bal is None:
        bal = float(pt-lo)/(hi-lo)
    lo = lo - bal*delta
    hi = hi + (1-bal)*delta

    # Convert transformed values back to the original scale
    if scale=='log':
        lo,hi = math.pow(10.,lo),math.pow(10.,hi)

    return (lo,hi)

def onWheel(event):
    """
    Process mouse wheel as zoom events
    """
    ax = event.inaxes

    # Older versions of matplotlib do not have event.step defined
    try:
        step = event.step
    except:
        if event.button == 'up':
            step = 1
        else:
            step = -1

    # Find colorbars attached to the canvas.
    # FIXME Better way to tell if axes contains colorbar?
    colorbars = getattr(event.canvas,'_colorbars',{})

    # If in plot, use the xdata, ydata as the center point
    # If not in plot, check if we are in a plot axis
    if ax == None:
        # Event not on plot: check if it happened in an axis
        xdata,ydata = None,None
        x,y = event.x,event.y
        axes = event.canvas.figure.get_axes()
        for ax in axes:
            inx,_ = ax.xaxis.contains(event)
            if inx:
                xdata,_ = ax.transData.inverted().transform_point((x,y))
                break
            iny,_ = ax.yaxis.contains(event)
            if iny:
                _,ydata = ax.transData.inverted().transform_point((x,y))
                break
        else:
            ax = None
    else:
        xdata,ydata = event.xdata,event.ydata

    if ax in colorbars:
        # Colorbar scrolling requires remapping the limits
        # Note that xdata,ydata are in 0,1, and so are implicitly the
        # balance point in the range of the data vlo,vhi
        if colorbars[ax].orientation is 'vertical':
            bal = ydata
        else:
            bal = xdata

        # The scroll event may not have occurred in the right direction
        if bal is not None:
            mappable = colorbars[ax].mappable
            if isinstance(mappable.norm,colors.LogNorm):
                vscale = 'log'
            else:
                vscale = 'linear'
            vlo,vhi = mappable.get_clim()
            vlo,vhi = _rescale(vlo,vhi,step,bal=bal,scale=vscale)
            mappable.set_clim(vlo,vhi)
            event.canvas.draw_idle()

    else:
        # Axis scrolling requires remapping the axis limits
        if xdata is not None:
            lo,hi = ax.get_xlim()
            lo,hi = _rescale(lo,hi,step,pt=xdata,scale=ax.get_xscale())
            ax.set_xlim((lo,hi))

        if ydata is not None:
            lo,hi = ax.get_ylim()
            lo,hi = _rescale(lo,hi,step,pt=ydata,scale=ax.get_yscale())
            ax.set_ylim((lo,hi))

        if xdata is not None or ydata is not None:
            event.canvas.draw_idle()

def colorbar(*args,**kw):
    cb = pylab.colorbar(*args,**kw)
    canvas = pylab.gcf().canvas
    if not hasattr(canvas,'_colorbars'):
        canvas._colorbars = {}
    canvas._colorbars[cb.ax] = cb



pylab.gcf().canvas.mpl_connect('scroll_event',onWheel)
 
pylab.subplot(211)
pylab.imshow([[1,2,3],[2,1,3]])
colorbar(orientation='horizontal')
pylab.subplot(212)
pylab.loglog([10,100,1000],[100,10,1000])
pylab.show()
-------------------------------------------------------------------------
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

Reply via email to