Plotting single marker point at zoomed level

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.

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 7:01 AM, New2Python <new2python@...2005...> 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

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

···

On Mon, May 26, 2008 at 10:08 AM, John Hunter <jdh2358@...287...> wrote:

On Mon, May 26, 2008 at 7:01 AM, New2Python <new2python@...2005...> 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

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 <jdh2358@...287...> wrote:

On Mon, May 26, 2008 at 7:01 AM, New2Python <new2python@...2005...> >> 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
Matplotlib-users@lists.sourceforge.net
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.

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

···

On Wed, May 28, 2008 at 7:10 AM, New2Python <new2python@...2005...> 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

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 <new2python@...2005...> > 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
Matplotlib-users@lists.sourceforge.net
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.