interacting with data plot

Hi all,

I have a plot of data that I am enabling
the user to interact with. That is, I want them to be able to pick a
point, and then have a new plot pop up in a different figure showing more info
about that point.

So, looking through the manual and the
tutorial I have taken the code from one of the examples and am trying to modify
it to work for my needs. Here’s what I have so far:

field = arrange(-1,1.25,0.25)

CA = cellArray() # this is an object
defined elsewhere.

Ij = # a list of 2d arrays of data

def state_picker(line, mouseevent):

        if

mouseevent.xdata is None:

                    return

False, dict()

        xdata

= line.get_xdata()

        ydata

= line.get_ydata()

        maxd

= 0.1

        d

= nx.sqrt((xdata - mouseevent.xdata)**2. + (ydata - mouseevent.ydata)**2.)

        ind = nx.nonzero(nx.less_equal(d,

maxd))

        if

len(ind):

                    out

= dict(ind=ind)

                    return

True, out

        else:

                    return

False, dict()

def onpick2(event,cellArray,Ij):

        Ij

= Ij[event.ind] # chose the list element from Ij corresponds to the point
selected by the user

        cellArray.plot('flux',inputIj=Ij)

the cellArray object has its own plot method that requires these two

arguments

fig = figure()

ax1 = fig.add_subplot(111)

ax1.set_title(‘Energy States vs. Applied
Flux per cell’)

for i in range(len(field)):

···
        #

energy is a list of arrays of different length

        ax1.plot(field[i]*ones(len(energy[i])),energy[i],'.b',

picker = state_picker)

ax1.set_xlim(-1.1,1.1)

ax1.set_xlabel(‘Applied Flux per cell’)

ax1.set_ylabel(‘Array Energy (Ej)’)

fig.canvas.mpl_connect(‘pick_event’,
onpick2)

show()

The problem I’m having is that I can’t
seem to pass extra arguments to either state_picker or onpick2. Can I?

thanks for your help,

trevis


Trevis Crane

Postdoctoral Research Assoc.

Department of Physics

University of Ilinois

1110 W. Green St.

Urbana, IL 61801

p: 217-244-8652

f: 217-244-2278

e: tcrane@…1315…


Here is an example that I just committed to svn as examples/pick_event_demo2.py

It made me realize that despite all my protestations not to repeatedly
call show, we do not have a backend dependent way to raise new figures
created in mpl callbacks. Since we've mostly made show bullet-proof
to repeated calls (because we don't restart the mainloops) this works,
but we do need a backend independent way to raise figures.

One approach would be to have the figure creation function (eg in the
backend) attach a method show() that raises the figure when called, eg
fig.show()

In any case, here is the example code, also attached in case the lines
get wrapped

"""
compute the mean and stddev of 100 data sets and plot mean vs stddev.
When you click on one of the mu, sigma points, plot the raw data from
the dataset that generated the mean and stddev
"""
import numpy
from pylab import figure, show

X = numpy.random.rand(100, 1000)
xs = numpy.mean(X, axis=1)
ys = numpy.std(X, axis=1)

fig = figure()
ax = fig.add_subplot(111)
ax.set_title('click on point to plot time series')
line, = ax.plot(xs, ys, 'o', picker=5) # 5 points tolerance

def onpick1(event):

    if event.artist!=line: return True

    N = len(event.ind)
    if not N: return True

    figi = figure()
    for subplotnum, dataind in enumerate(event.ind):
        ax = figi.add_subplot(N,1,subplotnum+1)
        ax.plot(X[dataind])
        ax.text(0.05, 0.9, 'mu=%1.3f\nsigma=%1.3f'%(xs[dataind], ys[dataind]),
                transform=ax.transAxes, va='top')
        ax.set_ylim(-0.5, 1.5)
        ax.figure.canvas.draw()
        print 'plotted'
    show() # oops, we need a way to raise figures created in callbacks
    return True

fig.canvas.mpl_connect('pick_event', onpick1)

show()

pick_event_demo2.py (1.08 KB)

···

On 6/8/07, Trevis Crane <t_crane@...1614...> wrote:

Hi all,

I have a plot of data that I am enabling the user to interact with. That
is, I want them to be able to pick a point, and then have a new plot pop up
in a different figure showing more info about that point.

I just made a minor modification to the backends (GTK, QT, QT4, Tk,
and WX) in the figure managers to attach a show method to the figure
class. It's not terribly elegant (and using this approach means it
will not show up properly in the class documentation) but it works.
If someone has a better, more elegant approach, I'm all for it, but at
least now you can do

  fig.show()

in pylab and it will do all the necessary GUI calls to raise the
window. I've tested on GTK* and TkAgg -- those of you with svn access
and WX* or QT* should test examples/pick_event_demo2.py on those
platforms.

The downside of this approach is that it makes porting pylab code to
embedded GUI code a little harder, but such is the price of
convenience.

JDH

···

On 6/8/07, John Hunter <jdh2358@...287...> wrote:

It made me realize that despite all my protestations not to repeatedly
call show, we do not have a backend dependent way to raise new figures
created in mpl callbacks. Since we've mostly made show bullet-proof
to repeated calls (because we don't restart the mainloops) this works,
but we do need a backend independent way to raise figures.