[英]Interactive plotting in matplotlib puzzle
我正在看一个使用matplotlib进行交互式绘图的示例(我在这里找到)
我刚刚将其修改为在函数(称为测试)中调用,如下所示
class PointBrowser:
def __init__(self,xs,ys):
self.xs = (xs)
self.ys = (ys)
self.fig = figure()
self.ax = self.fig.add_subplot(111)
self.line, = self.ax.plot(self.xs,self.ys,'ro ', picker=5)
self.lastind = 0
self.text = self.ax.text(0.05, 0.95, 'Datapoint index selected: none',
transform=self.ax.transAxes, va='top')
self.selected, = self.ax.plot([self.xs[0]],
[self.ys[0]], 'o', ms=12, alpha=0.4,
color='yellow', visible=False)
self.fig.canvas.mpl_connect('pick_event', self.onpick)
self.fig.canvas.mpl_connect('key_press_event', self.onpress)
def onpress(self, event):
'define some key press events'
if self.lastind is None: return
if event.key in ('q','Q'): sys.exit()
if event.key not in ('n', 'p'): return
if event.key=='n': inc = 1
else: inc = -1
self.lastind += inc
self.lastind = clip(self.lastind, 0, len(self.xs)-1)
self.update()
def onpick(self, event):
if event.artist!=self.line: return True
N = len(event.ind)
if not N: return True
if N > 1:
print '%i points found!' % N
# the click locations
x = event.mouseevent.xdata
y = event.mouseevent.ydata
dx = array(x-self.xs[event.ind],dtype=float)
dy = array(y-self.ys[event.ind],dtype=float)
distances = hypot(dx,dy)
indmin = distances.argmin()
dataind = event.ind[indmin]
self.lastind = dataind
self.update()
def update(self):
if self.lastind is None: return
dataind = self.lastind
self.selected.set_visible(True)
self.selected.set_data(self.xs[dataind], self.ys[dataind])
self.text.set_text('datapoint index selected: %d'%dataind)
# put a user function in here!
self.userfunc(dataind)
self.fig.canvas.draw()
def userfunc(self,dataind):
print 'No userfunc defined'
pass
def test():
import numpy as npy
X = npy.random.rand(100, 200)
xs = npy.mean(X, axis=1)
ys = npy.std(X, axis=1)
p = PointBrowser(xs,ys)
def plot2(dataind):
fig2 = figure(2)
ax2 = fig2.add_subplot(111)
ax2.cla()
ax2.plot(X[dataind])
ax2.text(0.05, 0.9, 'mu=%1.3f\nsigma=%1.3f'%(xs[dataind], ys[dataind]),
transform=ax2.transAxes, va='top')
ax2.set_ylim(-0.5, 1.5)
fig2.canvas.draw()
p.userfunc = plot2
xlabel('$\mu$')
ylabel('$\sigma$')
show()
if __name__ == '__main__':
test()
奇怪的是,它现在不起作用。 如果我删除该函数并将其主体放回“ if name ==' main '”块下,它将按预期工作(如原始代码中一样)。
我正在尝试生成交互式绘图,并将其作为正在构建的课程的一部分,但我对为什么会发生这种情况感到困惑。 有任何想法吗?
当我在ipython中运行您的代码时,我看到了同样的事情: onpick()
从未被调用。 从命令行调用python example_code.py
直接运行相同的代码在某种意义上可以正常工作,即调用了onpick()
方法。 但是,它不会显示第二个数字。 我认为这是事件循环的问题,但我不确定。
但是,如果要从ipython中运行代码,则可以使用以下代码,该代码用一个类替换嵌套函数的构造:
from numpy import *
from matplotlib.pyplot import *
class PointBrowser:
def __init__(self,xs,ys):
self.xs = (xs)
self.ys = (ys)
self.fig = figure()
self.ax = self.fig.add_subplot(111)
self.line, = self.ax.plot(self.xs,self.ys,'ro ', picker=5)
self.lastind = 0
self.text = self.ax.text(0.05, 0.95, 'Datapoint index selected: none',
transform=self.ax.transAxes, va='top')
self.selected, = self.ax.plot([self.xs[0]],
[self.ys[0]], 'o', ms=12, alpha=0.4,
color='yellow', visible=False)
self.fig.canvas.mpl_connect('pick_event', self.onpick)
self.fig.canvas.mpl_connect('key_press_event', self.onpress)
print "init done"
def onpress(self, event):
'define some key press events'
if self.lastind is None: return
if event.key in ('q','Q'): sys.exit()
if event.key not in ('n', 'p'): return
if event.key=='n': inc = 1
else: inc = -1
self.lastind += inc
self.lastind = clip(self.lastind, 0, len(self.xs)-1)
self.update()
def onpick(self, event):
print "in onpick"
if event.artist!=self.line: return True
N = len(event.ind)
if not N: return True
if N > 1:
print '%i points found!' % N
# the click locations
x = event.mouseevent.xdata
y = event.mouseevent.ydata
dx = array(x-self.xs[event.ind],dtype=float)
dy = array(y-self.ys[event.ind],dtype=float)
distances = hypot(dx,dy)
indmin = distances.argmin()
dataind = event.ind[indmin]
self.lastind = dataind
self.update()
def update(self):
print "in update"
if self.lastind is None: return
dataind = self.lastind
self.selected.set_visible(True)
self.selected.set_data(self.xs[dataind], self.ys[dataind])
self.text.set_text('datapoint index selected: %d'%dataind)
# put a user function in here!
self.userfunc(dataind)
self.fig.canvas.draw()
def userfunc(self,dataind):
print 'No userfunc defined'
pass
class Test2:
def __init__(self):
self.X = random.rand(100, 200)
self.xs = mean(self.X, axis=1)
self.ys = std(self.X, axis=1)
self.p = PointBrowser(self.xs,self.ys)
self.p.userfunc = self.plot2
xlabel('$\mu$')
ylabel('$\sigma$')
show()
def plot2(self, dataind):
fig2 = figure(2)
ax2 = fig2.add_subplot(111)
ax2.cla()
ax2.plot(self.X[dataind])
ax2.text(0.05, 0.9, 'mu=%1.3f\nsigma=%1.3f'%(self.xs[dataind], self.ys[dataind]),
transform=ax2.transAxes, va='top')
ax2.set_ylim(-0.5, 1.5)
fig2.canvas.draw()
if __name__ == '__main__':
Test2()
嵌套函数给您带来了自己的复杂程度,因为必须在嵌套函数已经终止时(如X
, xs
和ys
将嵌套级别的局部变量存储在闭包单元中,以便以后可以访问它们。在您的代码中)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.