From: Erik S. <oth...@gm...> - 2009-08-13 17:52:23
|
Good day, I've hit an issue that may be a bug. In a previous version of matplotlib (.98.x) I had a picker set for lines plotted on two axes. This was working until I upgraded to version 0.99.0. Now the first axes's pick events never seem to fire even though they respond true if queried with pickable(). The second axes's pick events still fire. Using the example below, clicking on the left y's line will never print anything, but the sin from the right will if clicked on. OS: Windows XP Pro Python: 2.6 matplotlib version: 0.99.0 -- installed using the python2.6 windows exe obtained from sourceforge Code to reproduce: import numpy as np import matplotlib.pyplot as plt fig = plt.figure() ax1 = fig.add_subplot(111) t = np.arange(0.01, 10.0, 0.01) s1 = np.exp(t) ax1.plot(t, s1, 'b-', picker = 4.0) ax1.set_xlabel('time (s)') # Make the y-axis label and tick labels match the line color. ax1.set_ylabel('exp', color='b') for tl in ax1.get_yticklabels(): tl.set_color('b') ax2 = ax1.twinx() s2 = np.sin(2*np.pi*t) ax2.plot(t, s2, 'r.', picker = 4.0) ax2.set_ylabel('sin', color='r') for tl in ax2.get_yticklabels(): tl.set_color('r') def onpick(event): thisline = event.artist xdata = thisline.get_xdata() ydata = thisline.get_ydata() ind = event.ind print 'onpick points:', zip(xdata[ind], ydata[ind]) fig.canvas.mpl_connect('pick_event', onpick) plt.show() Thanks for a wonderful plotting package! |
From: John H. <jd...@gm...> - 2009-08-19 19:04:25
|
On Thu, Aug 13, 2009 at 12:51 PM, Erik Schweller<oth...@gm...> wrote: > Good day, > > I've hit an issue that may be a bug. In a previous version of > matplotlib (.98.x) I had a picker set for lines plotted on two axes. > This was working until I upgraded to version 0.99.0. Now the first > axes's pick events never seem to fire even though they respond true if > queried with pickable(). The second axes's pick events still fire. > > Using the example below, clicking on the left y's line will never > print anything, but the sin from the right will if clicked on. I'm not sure why it worked before -- that surprises me. Only one axes can receive the pick event currently, so if you have overlapping axes, as you do with twinx, the one with the highest zorder will receive the pick events. By default, the zorder by the Axes is 0, so you could raise the twinx axes, by increaseing the zorder ax2.set_zorder(0.1) and then the line on that axes will respond to the pick events. With some work, we might be able to support multiple overlapping axes handling a single pick event. JDH |
From: othererik <oth...@gm...> - 2009-08-20 14:02:48
|
John, Thanks for the information. The solution worked so, I can now do a mouse over over lines from either axes and have a nice little tooltip, etc. I found that if I change the zorder of the axis right after attempting to "pick" on the mouse event, it fails, but it's fine for my needs to just toggle the "top" axes on mouse events when looking for a mouse hover. if self.ax.get_zorder() == 0.1: ax.set_zorder( 0 ) ax2.set_zorder( 0.1 ) else: ax2.set_zorder( 0 ) ax.set_zorder( 0.1 ) self.figure.pick( event ) This is perhaps a bit of hackery, but I've not seen any mouse over legends of the sorts built in. Thanks again, -Erik John Hunter-4 wrote: > > > I'm not sure why it worked before -- that surprises me. Only one axes > can receive the pick event currently, so if you have overlapping axes, > as you do with twinx, the one with the highest zorder will receive the > pick events. > > -- View this message in context: http://www.nabble.com/onpick-on-a-2-y-plot-%28-via-twinx%28%29-%29-seems-to-only-allow-picking-of-second-axes%27s-artists-tp25049128p25062402.html Sent from the matplotlib - users mailing list archive at Nabble.com. |
From: Stephan M. <zw...@we...> - 2011-01-20 09:44:09
|
Hello! I am also using two axes in a plot and want to be able to pick the lines of both axes. So far I used MPL 0.99.3 and a button on my interface to change the z-order of the axes in order to be able to pick lines of the "active" axes and to see the correct x/y data in the navigation toolbar. The callback code of my button is basically the code from othererik. Since MPL 1.0.0 I have the problem that lines of the second axes simply disappear from the plot whenever the plot is redrawn and it's zorder is higher. Here is my example code: http://old.nabble.com/file/p30717629/twinxtest.py twinxtest.py ----------------------- import matplotlib matplotlib.use('TkAgg') from numpy import arange, sin, pi, cos from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg from matplotlib.figure import Figure import Tkinter as Tk root = Tk.Tk() f = Figure(figsize=(5,4), dpi=100) ax1 = f.add_subplot(111) ax2 = ax1.twinx() t = arange(0.0,3.0,0.01) s1 = sin(2*pi*t) s2 = 2*cos(2*pi*t) ax1.plot(t,s1,color='red', picker=True) ax2.plot(t,s2,picker=True) def pick_cb(event): if event.artist.get_lw() > 1: event.artist.set_lw(1) else: event.artist.set_lw(3) f.canvas.draw() def toggle(): if ax1.get_zorder() == 0: ax1.set_zorder(0.1) ax2.set_zorder(0) else: ax1.set_zorder(0) ax2.set_zorder(0.1) canvas = FigureCanvasTkAgg(f, master=root) canvas.show() canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) toolbar = NavigationToolbar2TkAgg(canvas, root) toolbar.update() canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) canvas.mpl_connect('pick_event', pick_cb) button = Tk.Button(master=root, text='Toggle', command=toggle) button.pack(side=Tk.BOTTOM) Tk.mainloop() ------------------ Right after start I can only pick the blue line and both lines are properly shown even when I resize the plot. When I hit the "Toggle" button now I can pick the red line but the pick event callback also calls canvas.draw() which let's the blue line disappear. When I click "Toggle" and call canvas.draw() again by resizing the window, the blue line is visible again. In Matplotlib 0.99.3 everything worked as I expected with this code. Both lines were always visible. -Stephan -- View this message in context: http://old.nabble.com/onpick-on-a-2-y-plot-%28-via-twinx%28%29-%29-seems-to-only-allow-picking-of-second-axes%27s-artists-tp25049128p30717629.html Sent from the matplotlib - users mailing list archive at Nabble.com. |
From: Stephan M. <zw...@we...> - 2011-02-10 15:45:28
|
Right now I use a customized FigureCanvasTkAgg and overwrite the draw() and resize() methods to reset the z-order of the axes before drawing / resizing the figure and to restore the desired z-order afterwards. This works quite well but it would be nice to have the picking work like in version <=0.99.3. ----------------------- import matplotlib matplotlib.use('TkAgg') from numpy import arange, sin, pi, cos from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg from matplotlib.figure import Figure import Tkinter as Tk root = Tk.Tk() f = Figure(figsize=(5,4), dpi=100) ax0 = f.add_subplot(111) ax1 = ax0.twinx() t = arange(0.0,3.0,0.01) s1 = sin(2*pi*t) s2 = 2*cos(2*pi*t) ax0.plot(t,s1,color='red', picker=True) ax1.plot(t,s2,picker=True) ax0.my_zorder=0 ax1.my_zorder=0.1 class MyFigureCanvasTkAgg(FigureCanvasTkAgg): def draw(self): ax0 = self.figure.axes[0] ax1 = self.figure.axes[1] ax0.set_zorder(0) ax1.set_zorder(0) FigureCanvasTkAgg.draw(self) ax0.set_zorder(ax0.my_zorder) ax1.set_zorder(ax1.my_zorder) def resize(self, event): ax0 = self.figure.axes[0] ax1 = self.figure.axes[1] ax0.set_zorder(0) ax1.set_zorder(0) FigureCanvasTkAgg.resize(self, event) ax0.set_zorder(ax0.my_zorder) ax1.set_zorder(ax1.my_zorder) def pick_cb(event): if event.artist.get_lw() > 1: event.artist.set_lw(1) else: event.artist.set_lw(3) f.canvas.draw() def toggle(): if ax0.my_zorder == 0: ax0.my_zorder=0.1 ax1.my_zorder=0 else: ax0.my_zorder=0 ax1.my_zorder=0.1 ax0.set_zorder(ax0.my_zorder) ax1.set_zorder(ax1.my_zorder) canvas = MyFigureCanvasTkAgg(f, master=root) canvas.show() canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) toolbar = NavigationToolbar2TkAgg(canvas, root) toolbar.update() canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) canvas.mpl_connect('pick_event', pick_cb) button = Tk.Button(master=root, text='Toggle', command=toggle) button.pack(side=Tk.BOTTOM) Tk.mainloop() ----------------------- -- View this message in context: http://old.nabble.com/onpick-on-a-2-y-plot-%28-via-twinx%28%29-%29-seems-to-only-allow-picking-of-second-axes%27s-artists-tp25049128p30893570.html Sent from the matplotlib - users mailing list archive at Nabble.com. |
From: C M <cmp...@gm...> - 2011-02-11 17:10:34
|
On Thu, Jan 20, 2011 at 4:44 AM, Stephan Markus <zw...@we...> wrote: > > Hello! > > I am also using two axes in a plot and want to be able to pick the lines of > both axes. > So far I used MPL 0.99.3 and a button on my interface to change the z-order > of the axes in order to be able to pick lines of the "active" axes and to > see the correct x/y data in the navigation toolbar. The callback code of my > button is basically the code from othererik. > > Since MPL 1.0.0 I have the problem that lines of the second axes simply > disappear from the plot whenever the plot is redrawn and it's zorder is > higher. This thread, in which I asked a similar question and receive a workable solution from JJ, might be helpful. I am now just automatically moving all my lines over to the highest z-order axis so that whatever is visible is pickable. (But see below for a gotcha) http://old.nabble.com/unable-to-point-pick-2nd-axis-after-upgrade-to-mpl-1.0-td30400311.html On this note, to the developers: This need to take into account the z-order for picking lines has made my development more difficult. I have had a week's delay due to a difficult-to-understand bug in my code in which I prematurely moved the line over to the highest z-order axis, and then tried to format the axis with a custom formatter--causing an error. Simply moving the line only after all formatting is done fixed the bug, but that wasn't obvious for a while. The need to track which lines are on which z-order and to move them only after all formatting/locating has been done on them strikes me as a new "gotcha" that the simpler and more intuitive approach of "if you can see it, you can pick it" didn't have. (I have a somewhat complex case, though, in which there are three possible sorts of axes that could wind up on either the right or left sides). It also seems counter-intuitive that a line can "belong" to an axis from the in Matplotlib and yet for the user it clearly is measured using the other axis. Could "z-order mattering" be toggled? Anyway, my 2 cents. Thanks, Che |
From: Stephan M. <zw...@we...> - 2011-02-14 09:11:59
|
That solution might be fine for static plots, but I my case I prefer my solution. My plot is quite interactive so using your solution causes many problems with my code. -- View this message in context: http://old.nabble.com/onpick-on-a-2-y-plot-%28-via-twinx%28%29-%29-seems-to-only-allow-picking-of-second-axes%27s-artists-tp25049128p30919747.html Sent from the matplotlib - users mailing list archive at Nabble.com. |