Hi All, I hope someone can give me a simple solution to my problem. I have a line plotted and I need to be able to mark selected data points on the line. I am using the mpl_connect function to detect the mouseclick on the line and then to place a marker at the selected datapoint. My data is 0.2s apart on a 1hour plot, so to click on a single data point i need to zoom into the graph. Once I zoom in and select the data point, the marker doesn't appear until the graph is resized or refreshed by the home button. Also, if I click on an existing datapoint, is is removed in the array however when the graph is redrawn or refreshed the marker is not deleted. Below is an exert of the code. I am using embedded_wx4.py as a template. So the question is, how can i show the marker at the zoomed level, it is apain to have to zoom out to home view every time and why won't my redraw work. If there is any ambiguity please let me know and I'll try to re-explain myself. def _on_addmarker(self, evt): #defined from toolbar button datamarker = self.canvas.mpl_connect('pick_event', self.onpick1) evt.Skip() def onpick1(self, event): self.background_marker=self.canvas.copy_from_bbox(self.axes.bbox) self.marker, = self.axes.plot(x,y, 'go',markersize=8) if isinstance(event.artist, Line2D): thisline=event.artist xdata = thisline.get_xdata() ydata = thisline.get_ydata() ind = event.ind tempx = xdata[ind] tempy = ydata[ind] print '------------' print 'onpick1 line X:' ,tempx print 'onpick1 line ind:' ,ind print 'onpick1 line Y:' ,tempy if xdata[ind] in x: x.remove(tempx) y.remove(tempy) print '------------' print 'you removed ' ,ind ,tempx ,tempy print 'X=' ,x print 'Y=' ,y print '------------' else: x.append(tempx) y.append(tempy) print 'you clicked ' ,x ,y print '------------' time.sleep(0.1) #----------------------------------------------------------------------------------------- self.canvas.restore_region(self.background_marker) self.marker.set_data(x,y) self.axes.draw_artist(self.marker) self.canvas.blit(self.axes.bbox) and class CanvasFrame(Frame): global line, background def __init__(self): Frame.__init__(self,None,-1, 'CanvasFrame',size=(550,350)) self.SetBackgroundColour(NamedColor("WHITE")) self.figure = Figure(figsize=(5,4), dpi=100) self.axes = self.figure.add_subplot(111) picker = 5 self.line, = self.axes.plot(cx,cy,picker=picker, linewidth=1) etc..etc... -- View this message in context: http://www.nabble.com/Plotting-single-marker-point-at-zoomed-level-tp17470649p17470649.html Sent from the matplotlib - users mailing list archive at Nabble.com.
On Mon, May 26, 2008 at 7:01 AM, New2Python <new...@li...> wrote: > I hope someone can give me a simple solution to my problem. I have a line > plotted and I need to be able to mark selected data points on the line. I am If you are frequently changing the zoom level, as it looks like you are, the copy background/restore region/blit idiom is probably not the right one for you, since the background is assumed fixed. You can simply force a draw at any time by doing fig.canvas.draw() w/o having to zoom out or resize to trigger a draw. So after doing the self.marker.set_data call, I would do fig.canvas.draw If you have a lot of data and only a little in the viewport and efficiency is a concern, you can use a "clipped line" class, as in the example http://matplotlib.sf.net/examples/clippedline.py Let me know if this helps, JDH
On Mon, May 26, 2008 at 10:08 AM, John Hunter <jd...@gm...> wrote: > On Mon, May 26, 2008 at 7:01 AM, New2Python <new...@li...> wrote: > >> I hope someone can give me a simple solution to my problem. I have a line >> plotted and I need to be able to mark selected data points on the line. I am > > If you are frequently changing the zoom level, as it looks like you > are, the copy background/restore region/blit idiom is probably not the > right one for you, since the background is assumed fixed. You can > simply force a draw at any time by doing fig.canvas.draw() w/o having > to zoom out or resize to trigger a draw. So after doing the > self.marker.set_data call, I would do fig.canvas.draw I thought this would be a generally useful thing to do (maintain a list of toggleable selected vertices) so I added some support. Here is some example code to highlight the selected markers: """ The matplotlib.lines.VertexSelector maintains a list of selected line vertices using the line picker property. If an unselected vertex is clicked, it is selected, and if a selected vertex is clicked, it is unselectedit. Classes which inherit from the VertexSelector should override the process_selected method to do something with the selected vertex. This example just highlights them with red markers. If you don't have access to svn, I can send you a free-standing example. """ The matplotlib.lines.VertexSelector maintains a list of selected line vertices using the line picker property. If an unselected vertex is clicked, it is selected, and if a selected vertex is clicked, it is unselectedit. Classes which inherit from the VertexSelector should override the process_selected method to do something with the selected vertex. This example just highlights them with red markers. """ import numpy as np import matplotlib.pyplot as plt import matplotlib.lines as lines class HighlightSelected(lines.VertexSelector): """ Highlight the selected vertices with a marker plot """ def __init__(self, line, fmt='ro', **kwargs): """ highlight the selected vertices of line with a marker plot. The plot format string are given by fmt and the kwargs are additional line properties """ lines.VertexSelector.__init__(self, line) self.markers, = self.axes.plot([], [], fmt, **kwargs) def process_selected(self, ind, xs, ys): """ ind are the indices of the selected vertices. xs and ys are the coordinates of the selected vertices. """ self.markers.set_data(xs, ys) self.canvas.draw() fig = plt.figure() ax = fig.add_subplot(111) x, y = np.random.rand(2, 30) line, = ax.plot(x, y, 'bs-', picker=5) selector = HighlightSelected(line) plt.show()
Thanks for that, the canvas.draw() function redraws the graph. I had to add the "autoscale_on=False" to the add_subplot() to stop the graph from autoscaling. One issue that I find now is that the removed marker is not redrawn as removed, in other words, all the original markers remain drawn whether or not the datapoints exist in the array. How can I remove the marker I don't want anymore withought doing a clf() call because I can have over 300,000 datapoints and the redraw will take ages Thanks for the link to the clipping code, that will come in handy. Much appreciated John Hunter-4 wrote: > > On Mon, May 26, 2008 at 10:08 AM, John Hunter <jd...@gm...> wrote: >> On Mon, May 26, 2008 at 7:01 AM, New2Python <new...@li...> >> wrote: >> >>> I hope someone can give me a simple solution to my problem. I have a >>> line >>> plotted and I need to be able to mark selected data points on the line. >>> I am >> >> If you are frequently changing the zoom level, as it looks like you >> are, the copy background/restore region/blit idiom is probably not the >> right one for you, since the background is assumed fixed. You can >> simply force a draw at any time by doing fig.canvas.draw() w/o having >> to zoom out or resize to trigger a draw. So after doing the >> self.marker.set_data call, I would do fig.canvas.draw > > I thought this would be a generally useful thing to do (maintain a > list of toggleable selected vertices) so I added some support. Here is > some example code to highlight the selected markers: > > """ > The matplotlib.lines.VertexSelector maintains a list of selected line > vertices using the line picker property. If an unselected vertex is > clicked, it is selected, and if a selected vertex is clicked, it is > unselectedit. > > Classes which inherit from the VertexSelector should override the > process_selected method to do something with the selected vertex. This > example just highlights them with red markers. If you don't have > access to svn, I can send you a free-standing example. > > > """ > The matplotlib.lines.VertexSelector maintains a list of selected line > vertices using the line picker property. If an unselected vertex is > clicked, it is selected, and if a selected vertex is clicked, it is > unselectedit. > > Classes which inherit from the VertexSelector should override the > process_selected method to do something with the selected vertex. This > example just highlights them with red markers. > > """ > > import numpy as np > import matplotlib.pyplot as plt > import matplotlib.lines as lines > > class HighlightSelected(lines.VertexSelector): > """ > Highlight the selected vertices with a marker plot > """ > def __init__(self, line, fmt='ro', **kwargs): > """ > highlight the selected vertices of line with a marker plot. > The plot format string are given by fmt and the kwargs are > additional > line properties > """ > lines.VertexSelector.__init__(self, line) > self.markers, = self.axes.plot([], [], fmt, **kwargs) > > def process_selected(self, ind, xs, ys): > """ > ind are the indices of the selected vertices. xs and ys are > the coordinates of the selected vertices. > """ > self.markers.set_data(xs, ys) > self.canvas.draw() > > fig = plt.figure() > ax = fig.add_subplot(111) > x, y = np.random.rand(2, 30) > line, = ax.plot(x, y, 'bs-', picker=5) > > selector = HighlightSelected(line) > plt.show() > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > Matplotlib-users mailing list > Mat...@li... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > > -- View this message in context: http://www.nabble.com/Plotting-single-marker-point-at-zoomed-level-tp17470649p17511209.html Sent from the matplotlib - users mailing list archive at Nabble.com.
On Wed, May 28, 2008 at 7:10 AM, New2Python <new...@li...> wrote: > One issue that I find now is that the removed marker is not redrawn as > removed, in other words, all the original markers remain drawn whether or > not the datapoints exist in the array. How can I remove the marker I don't > want anymore withought doing a clf() call because I can have over 300,000 > datapoints and the redraw will take ages You will need to do some extra work here. I would have a "picking mode" which is enabled by a key-stroke or button press, and when the mode is enabled, you can copy the background using the copy_background/restore region/blit techniques discussed at http://www.scipy.org/Cookbook/Matplotlib/Animations. Then you can mark your vertices and just draw the vertex marker line over the background. Alternatively, you can use the clipped line approach I pointed you to in my prior post to only plot the vertices in the viewport. You will have to do a little bookkeeping to translate the marked vertices in the viewport to the ones in the original dataset. Unfortunately, I don't have time to write the complete example right now... JDH
Thanks for that, I already have a button to enable picking mode and the original post shows that I have already tried the copy background/restore/blit, however I must have been doing something wrong. Pehaps you can point out what the issue was ro where I was going wrong John Hunter-4 wrote: > > On Wed, May 28, 2008 at 7:10 AM, New2Python <new...@li...> > wrote: > >> One issue that I find now is that the removed marker is not redrawn as >> removed, in other words, all the original markers remain drawn whether or >> not the datapoints exist in the array. How can I remove the marker I >> don't >> want anymore withought doing a clf() call because I can have over 300,000 >> datapoints and the redraw will take ages > > You will need to do some extra work here. I would have a "picking > mode" which is enabled by a key-stroke or button press, and when the > mode is enabled, you can copy the background using the > copy_background/restore region/blit techniques discussed at > http://www.scipy.org/Cookbook/Matplotlib/Animations. Then you can > mark your vertices and just draw the vertex marker line over the > background. Alternatively, you can use the clipped line approach I > pointed you to in my prior post to only plot the vertices in the > viewport. You will have to do a little bookkeeping to translate the > marked vertices in the viewport to the ones in the original dataset. > > Unfortunately, I don't have time to write the complete example right > now... > > JDH > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > Matplotlib-users mailing list > Mat...@li... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > > -- View this message in context: http://www.nabble.com/Plotting-single-marker-point-at-zoomed-level-tp17470649p17550943.html Sent from the matplotlib - users mailing list archive at Nabble.com.