<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>scienceoss.com &#187; interactive</title>
	<atom:link href="http://scienceoss.com/tags/interactive/feed/" rel="self" type="application/rss+xml" />
	<link>http://scienceoss.com</link>
	<description>useful tidbits for using open source software in science</description>
	<lastBuildDate>Wed, 26 May 2010 03:34:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Interactively select points from a plot  in matplotlib</title>
		<link>http://scienceoss.com/interactively-select-points-from-a-plot-in-matplotlib/</link>
		<comments>http://scienceoss.com/interactively-select-points-from-a-plot-in-matplotlib/#comments</comments>
		<pubDate>Mon, 28 Jan 2008 19:30:15 +0000</pubDate>
		<dc:creator>ryan</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[matplotlib]]></category>
		<category><![CDATA[plotting]]></category>
		<category><![CDATA[ginput]]></category>
		<category><![CDATA[interactive]]></category>
		<category><![CDATA[select points]]></category>

		<guid isPermaLink="false">http://scienceoss.com/?p=14</guid>
		<description><![CDATA[In Matlab, there is a very useful function called ginput(). There is no such ready-built function for matplotlib/pylab, but all the pieces are there. Copy and paste this code to get ginput functionality. The code is below if you want to jump right to it. Here&#8217;s a little explanation of what&#8217;s happening: The general idea [...]]]></description>
			<content:encoded><![CDATA[<p>In Matlab, there is a very useful function called <span class="c">ginput()</span>.  There is no such ready-built function for matplotlib/pylab, but all the pieces are there.  Copy and paste this code to get ginput functionality.<br />
<span id="more-14"></span><br />
The code is below if you want to jump right to it.</p>
<p>Here&#8217;s a little explanation of what&#8217;s happening:</p>
<p>The general idea is to create a class, the <span class="c">MouseMonitor</span>, that will hold the x and y data coordinates.  This class has a single method, the <span class="c">mycall()</span> method.  <em>Note: you could be tricky and define a <span class="c">__call__</span> method, and save a few keystrokes by just passing <span class="c">mouse</span> (instead of <span class="c">mouse.mycall</span>) to the <span class="c">connect</span> function.  I didn&#8217;t do that here cause it&#8217;s harder to explain.</em></p>
<p>The <span class="c">connect()</span> function needs, as its first argument, the name of an event.  Possible events are &#8216;resize_event&#8217;, &#8216;draw_event&#8217;, &#8216;key_press_event&#8217;, &#8216;key_release_event&#8217;, &#8216;button_press_event&#8217;, &#8216;button_release_event&#8217;, &#8216;motion_notify_event&#8217;, and &#8216;pick_event&#8217;.</p>
<p>The second argument to <span class="c">connect()</span> needs to be the name of a function that will be called every time that event happens.  In this case, it&#8217;s the <span class="c">mycall</span> method of the <span class="c">mouse</span> object, <span class="c">mouse.mycall</span>.</p>
<p>Since mouse.mycall is the callback function given to connect, it will be called every time there is a button press event.  So every time you click on the plot, <span class="c">mouse.mycall</span> it will append the x and y coords to its own internal list, print the x and y coords, plot a red circle, and refresh the plot every time.</p>
<p>When you&#8217;re done, you can access the x and y data in mouse with <span class="c">mouse.xdatalist</span> and <span class="c">mouse.ydatalist</span>.</p>
<p>More examples to follow, but for now here&#8217;s a basic version that improve a little on the functionality of Matlab&#8217;s ginput (which doesn&#8217;t give you graphical feedback on its own).</p>
<pre class = "prettyprint"><code class = "code">
from pylab import *
class MouseMonitor:
    event = None
    xdatalist = []
    ydatalist = []

    def mycall(self, event):
        self.event = event
        self.xdatalist.append(event.xdata)
        self.ydatalist.append(event.ydata)

        print 'x = %s and y = %s' % (event.xdata,event.ydata)

        ax = gca()  # get current axis
        ax.hold(True) # overlay plots.

        # Plot a red circle where you clicked.
        ax.plot([event.xdata],[event.ydata],'ro')

        draw()  # to refresh the plot.

if __name__=="__main__":
    # Example usage
    mouse = MouseMonitor()
    connect('button_press_event', mouse.mycall)
    plot([1,2,3])
    show()
</code></pre>
<h2>An improved version</h2>
<p>The following code allows you to set up a MouseMonitor object that plots multiple sets of data.</p>
<pre class="prettyprint"><code class="code">from pylab import *
import sys
class MouseMonitor:
    event = None
    xdatalist = []
    ydatalist = []

    def my_call(self, event):
        self.event = event

        if event.button == 1:
            self.xdatalist.append(event.xdata)
            self.ydatalist.append(event.ydata)

            sys.stdout.flush()
            print 'x = %s and y = %s' % (event.xdata,event.ydata)
            sys.stdout.flush()
            ax = gca()
            ax.hold(True)
            ax.plot([event.xdata],[event.ydata],'ro')

            draw()

        if event.button == 3:
            disconnect(self.cid)
            self.ask_for_another()

    def ask_for_another(self):
        sys.stdout.flush()
        answer = raw_input('Press n for the next plot, or any other key to stop:  ')
        if answer == 'n':
            self.plot_next()
        else:
            print '::sniff::  bye'
            close('all')

    def set_data(self,x,y):
        self.xlist = x
        self.ylist = y
        self.i = 0

    def plot_next(self):
        if self.i < len(self.xlist):
            cla()
            plot(xlist[self.i],ylist[self.i])
            self.i += 1
            self.connect_to_plot()
            draw()
        else:
            sys.stdout.flush()
            print 'all out of data.'

    def connect_to_plot(self):
        self.cid = connect('button_press_event',self.my_call)

if __name__ == "__main__":
    mouse = MouseMonitor()

    xlist = [[1,2,3],[4,5,6]]
    ylist = [[3,4,5],[8,9,7]]

    mouse.set_data(xlist,ylist)

    mouse.plot_next()

    show()</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://scienceoss.com/interactively-select-points-from-a-plot-in-matplotlib/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
