Hi,
I am trying to use matplotlib to visually explore some data. I started
from the "event_handling example code: data_browser.py" example, but
wanted to go a bit further. The idea is to have two plots and an image
linked together. The first plot represents a measure calculated from
an image region at different times of the day. Selecting one of this
measures shows the corresponding image, and some other measure calculated
from the individual pixels. Further on, selecting in the image or the
second plot should highlight the corresponding point in the plot or pixel
on the image, respectively (That is, the first plot is linked to the image,
and the image and the second plot are linked together).
My problem is that on the function being called upon and event, I always
get events generated by the image, even when the moused was clicked on one of
the other plots. The plots behave ok.
The coded below is a simplified functional version (the measures here are
trivial, and I haven't included the actions when the user selects the image or
the second plot), which exhibits this behavior. What I see when executing this
code is for example:
Actions (click on) Results (from the print statement on the
onpick() function)
plot1 plot1
image2
image2 image2
plot3 plot3
image2
Am I doing something wrong? I am new to both python and matplotlib, so if you
see something that could be done in a better way, please tell me.
Jorges
----- Test code -----
import os
import sys
import glob
import re
import fnmatch
import Image as im
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import scipy as sp
import scipy.stats
class LCRBrowser():
"""
Permits to visualize log chromaticity ratios and related things for
analysing static images taken at throughout a period of time
"""
def __init__(self, data):
# Initialize instance attributes
self.lcr = np.asarray(map((lambda x: x['lcr']), data))
self.lcr_ind = np.asarray(map((lambda x: x['lcr_ind']), data))
self.img = np.asarray(map((lambda x: x['img']), data))
self.lastind = 0
# Initial drawing and picking init
self.fig = plt.figure()
self.ax1 = self.fig.add_subplot(311)
self.ax2 = self.fig.add_subplot(312)
self.ax3 = self.fig.add_subplot(313)
self.plot1, = self.ax1.plot(self.lcr, 'o', picker=5)
self.selected, = self.ax1.plot([self.lcr[0]], 'o', ms=12, alpha=0.4,
color='yellow', visible=False)
self.img2 = self.ax2.imshow(self.img[0], visible=True, picker=2,\
interpolation='nearest')
self.plot3, = self.ax3.plot(self.lcr_ind[0][:], 'o', visible=True, picker=5)
print type(self.plot3)
self.fig.canvas.mpl_connect('pick_event', self.onpick)
self.fig.canvas.draw()
def onpick(self, event):
x2 = event.mouseevent.ydata
if event.artist == self.plot1:
print 'plot1\n'
N = len(event.ind)
if not N: return True
distances = x2-self.lcr[event.ind]
indmin = distances.argmin()
dataind = event.ind[indmin]
self.lastind = dataind
elif event.artist == self.img2:
print 'img2\n'
elif event.artist == self.plot3:
print 'plot3\n'
else:
print 'didn\'t detect artist'
print str(event.artist)
return True
self.update()
def update(self):
if self.lastind is None: return
ind = self.lastind
self.img2.set_data(self.img[ind])
a = self.lcr_ind[ind][:]
self.plot3.set_data((range(len(a)), a))
self.fig.canvas.draw()
def main():
results = []
for name in range(5):
img = np.random.rand(5,4,3)
lcr = sp.stats.gmean(np.mean(np.mean(img, 0), 0))
lcr_ind = sp.stats.gmean(img, 2).reshape(-1,1)
result = {'lcr': lcr, 'lcr_ind':lcr_ind, 'img':img}
results.append(result)
LCRBrowser(results)
if __name__ == '__main__':
main()
----- code end -----