|
From: Srinath A. <sr...@fa...> - 2004-04-17 08:22:22
|
On Fri, 16 Apr 2004, John Hunter wrote:
> Yes, this would be a very nive feature. When you implement it, please
> send it back to the list. Here is an example that shows you how to
> connect to the events and more importantly for you, convert to user
> coords
>
Here's a very preliminary implementation. Its not really very elegant,
but it seems to work. A couple of questions. Is there a remove_line or
equivalent for axes? As of now, I make the rectangle which shows the
zoom window dissapear by setting its xdata and ydata to [], but it might
be elegant to just remove the line from the axis completely. Also I seem
to trigger a matplotlib bug if I toggle the zoom button and then start
the button press event outside the axes.
I have yet to delve into the matplotlib source itself and maybe I am not
the best person to do it. The best place to add this would be to extend
the axes class with a .zoom() method which would work like the
ZoomButtonPressed() function below (It basically makes the next button
press trigger the ZoomStart() function which in turn calls
ZoomContinue() on the "motion_notify_event"). ZoomStart() will have to
be modified to account for more than one axes belonging to a figure.
We'll have to check whether the user presses the mouse in the axes whos
.zoom() function has been called.
Thanks again for all the help :) I think I am almost ready to get things
working with matplotlib.
--
Srinath
from matplotlib.numerix import arange, sin, cos, pi
import matplotlib
matplotlib.use('GTK')
from matplotlib.backends.backend_gtk import FigureCanvasGTK
from matplotlib.axes import Subplot
from matplotlib.figure import Figure
import gtk
class MyApp:
def __init__(self):
self.win = gtk.Window()
self.win.set_name("Embedding in GTK")
self.win.connect("destroy", gtk.mainquit)
self.win.set_border_width(5)
self.vbox = gtk.VBox(spacing=3)
self.win.add(self.vbox)
self.vbox.show()
self.fig = Figure(figsize=(5,4), dpi=100)
self.ax = Subplot(self.fig, 111)
self.ax.plot([0,1], [0,1])
self.fig.add_axis(self.ax)
self.canvas = FigureCanvasGTK(self.fig) # a gtk.DrawingArea
self.canvas.show()
self.canvas.connect('motion_notify_event', self.setAxisCursorLocation)
self.vbox.pack_start(self.canvas)
buttonZoom = gtk.ToggleButton('Toggle Zoom')
buttonZoom.connect('button_press_event', self.ZoomButtonPressed)
buttonZoom.show()
self.vbox.pack_start(buttonZoom)
self.win.show()
def setAxisCursorLocation(self, widget, event):
height = self.canvas.figure.bbox.y.interval()
x, y = event.x, height-event.y
t = self.ax.xaxis.transData.inverse_positions(x)
val = self.ax.yaxis.transData.inverse_positions(y)
self.cursorLocation = (t, val)
def getAxisCursorLocation(self):
if not hasattr(self, 'cursorLocation'):
return None
return self.cursorLocation
def ZoomButtonPressed(self, widget, event):
if not widget.get_active():
self.zoomStartEventHandle = self.canvas.connect('button_press_event', self.ZoomStart)
else:
if hasattr(self, 'zoomStartEventHandle'):
self.canvas.disconnect(self.zoomStartEventHandle)
def ZoomStart(self, widget, event):
self.zoomStartPosition = self.getAxisCursorLocation()
x, y = self.zoomStartPosition
if hasattr(self, 'zoomRectangle'):
self.zoomRectangle.set_xdata([x,x,x,x,x])
self.zoomRectangle.set_ydata([y,y,y,y,y])
else:
self.zoomRectangle = self.ax.plot([x,x,x,x,x], [y,y,y,y,y], 'k:')[0]
self.zoomContinueEventHandle = self.canvas.connect_after('motion_notify_event', self.ZoomContinue)
self.zoomStopEventHandle = self.canvas.connect('button_release_event', self.ZoomStop)
def ZoomContinue(self, widget, event):
xs, ys = self.zoomStartPosition
x, y = self.getAxisCursorLocation()
self.zoomRectangle.set_xdata([xs, x, x, xs, xs])
self.zoomRectangle.set_ydata([ys, ys, y, y, ys])
self.canvas.draw()
def ZoomStop(self, widget, event):
self.canvas.disconnect(self.zoomContinueEventHandle)
self.canvas.disconnect(self.zoomStopEventHandle)
self.zoomRectangle.set_xdata([])
self.zoomRectangle.set_ydata([])
xs, ys = self.zoomStartPosition
x, y = self.getAxisCursorLocation()
self.ax.set_xlim([min([xs,x]), max([xs,x])])
self.ax.set_ylim([min([ys,y]), max([ys,y])])
self.canvas.draw()
if __name__=='__main__':
app = MyApp()
gtk.mainloop()
|