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() |