Hi,
In my attempt to get scroll wheel zooming working for this release I added
support for the scroll wheel to TkAgg, and added support for draw_idle to
the wx backend.
I'm attaching the wheel zoom demonstration code. This is standalone code
which is not yet ready to go into backend_bases. It only supports linear
and log axes. Using transform magic would be better here. Also, colormap
zooming is hacked (I don't know how to determine if the axes contain a
colorbar, and what the corresponding mappable is, so I put a list of
colorbars in the figure).
In the process of developing this code I noticed that a lot of the contains
tests are broken by the new transforms. Try attaching onHilite to the
motion notify event on any canvas --- objects should turn light blue as you
hover over them.
E.g.,
from pylab import plot, gcf, show
plot([1,2,3],[1,5,2])
cvs = gcf().canvas
cvs.mpl_connect('motion_notify_event',cvs.onHilite)
show()
I can fixes the axis hit test. I'm not sure how many other problems there
are, but I'm pretty sure I won't get to them all before next Tuesday.
- 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
try:
step = event.step
except:
if event.button == 'up':
step = 1
else:
step = -1
print "zoom",step
# Ick! Can't tell if the axes contains a colorbar.
if hasattr(event.canvas,'_colorbars') and ax in event.canvas._colorbars:
mappable = event.canvas._colorbars[ax].mappable
# rescale colormap: the axes are already scaled to 0..1,
# so use bal instead of pt for centering
lo,hi = mappable.get_clim()
if isinstance(mappable.norm,colors.LogNorm):
vscale = 'log'
else:
vscale = 'linear'
lo,hi = _rescale(lo,hi,step,bal=event.ydata,scale=vscale)
mappable.set_clim(lo,hi)
elif ax != None:
# Event occurred inside a plotting area
lo,hi = ax.get_xlim()
lo,hi = _rescale(lo,hi,step,pt=event.xdata,scale=ax.get_xscale())
ax.set_xlim((lo,hi))
lo,hi = ax.get_ylim()
lo,hi = _rescale(lo,hi,step,pt=event.ydata,scale=ax.get_yscale())
ax.set_ylim((lo,hi))
else:
# Check if zoom happens in the axes
xdata,ydata = None,None
x,y = event.x,event.y
for ax in event.canvas.figure.get_axes():
if ax.xaxis.contains(event):
xdata,_ = ax.transAxes.inverted().transform_point((x,y))
#print "xaxis",x,"->",xdata
if ax.yaxis.contains(event):
_,ydata = ax.transAxes.inverted().transform_point((x,y))
#print "yaxis",y,"->",ydata
if xdata is not None:
lo,hi = ax.get_xlim()
lo,hi = _rescale(lo,hi,step,bal=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,bal=ydata,scale=ax.get_yscale())
ax.set_ylim((lo,hi))
event.canvas.draw_idle()
def colorbar():
cb = pylab.colorbar()
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()
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