matplotlib show()不能工作两次 [英] matplotlib show() doesn't work twice
问题描述
我对matplotlib有一个奇怪的问题.如果运行此程序,则可以多次打开和关闭同一图.
I have a strange problem, with matplotlib. If I run this program, I'm able to open and close several time the same figure.
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 onpick(event):
figi = figure()
ax = figi.add_subplot(111)
ax.plot([1,2,3,4])
figi.show()
fig.canvas.mpl_connect('pick_event', onpick)
show()
相反,如果我在自定义小部件中使用相同的onpick函数代码,则它只会在第一次打开图形,在其他事件中,它会进入函数,但不会显示图形:
On the contrary, if I use the same code of onpick function into my custom widget it opens the figure only the first time, into the other events it enters into the functions but doesn't display the figure:
from PyQt4 import QtGui, QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt4 import NavigationToolbar2QT as NavigationToolbar
import time
STEP = 0.000152
class MplCanvas(FigureCanvas):
def __init__(self):
# initialization of the canvas
FigureCanvas.__init__(self, Figure())
self.queue = []
self.I_data = np.array([])
self.T_data = np.array([])
self.LvsT = self.figure.add_subplot(111)
self.LvsT.set_xlabel('Time, s')
self.LvsT.set_ylabel('PMT Voltage, V')
self.LvsT.set_title("Light vs Time")
self.LvsT.grid(True)
self.old_size = self.LvsT.bbox.width, self.LvsT.bbox.height
self.LvsT_background = self.copy_from_bbox(self.LvsT.bbox)
self.LvsT_plot, = self.LvsT.plot(self.T_data,self.I_data)
#self.LvsT_plot2, = self.LvsT.plot(self.T_data2,self.I_data2)
self.mpl_connect('axes_enter_event', self.enter_axes)
self.mpl_connect('button_press_event', self.onpick)
self.count = 0
self.draw()
def enter_axes(self,event):
print "dentro"
def onpick(self,event):
print "click"
print 'you pressed', event.canvas
a = np.arange(10)
print a
print self.count
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(a)
fig.show()
def Start_Plot(self,q,Vmin,Vmax,ScanRate,Cycles):
self.queue = q
self.LvsT.clear()
self.LvsT.set_xlim(0,abs(Vmin-Vmax)/ScanRate*Cycles)
self.LvsT.set_ylim(-3, 3)
self.LvsT.set_autoscale_on(False)
self.LvsT.clear()
self.draw()
self.T_data = np.array([])
self.I_data = np.array([])
# call the update method (to speed-up visualization)
self.timerEvent(None)
# start timer, trigger event every 1000 millisecs (=1sec)
self.timerLvsT = self.startTimer(3)
def timerEvent(self, evt):
current_size = self.LvsT.bbox.width, self.LvsT.bbox.height
if self.old_size != current_size:
self.old_size = current_size
self.LvsT.clear()
self.LvsT.grid()
self.draw()
self.LvsT_background = self.copy_from_bbox(self.LvsT.bbox)
self.restore_region(self.LvsT_background, bbox=self.LvsT.bbox)
result = self.queue.get()
if result == 'STOP':
self.LvsT.draw_artist(self.LvsT_plot)
self.killTimer(self.timerLvsT)
print "Plot finito LvsT"
else:
# append new data to the datasets
self.T_data = np.append(self.T_data,result[0:len(result)/2])
self.I_data = np.append(self.I_data,result[len(result)/2:len(result)])
self.LvsT_plot.set_data(self.T_data,self.I_data)#L_data
#self.LvsT_plot2.set_data(self.T_data2,self.I_data2)#L_data
self.LvsT.draw_artist(self.LvsT_plot)
self.blit(self.LvsT.bbox)
class LvsT_MplWidget(QtGui.QWidget):
def __init__(self, parent = None):
QtGui.QWidget.__init__(self, parent)
self.canvas = MplCanvas()
self.vbl = QtGui.QVBoxLayout()
self.vbl.addWidget(self.canvas)
self.setLayout(self.vbl)
动画图需要此小部件,当我单击该图完成实验后,它应该会出现一个图形,这只是第一次出现.
This widget is needed for an animation plot and when the experiment is finished if I click on the plot it should appear a figure, that appears only the first time.
你有什么线索吗?
非常感谢您.
推荐答案
我有关于Google搜索的新信息
I have new information about this that a google search turned up
这是来自matplotlib的作者.这来自 http://old. nabble.com/calling-show%28%29-twice-in-a-row-td24276907.html
This is from the writer of matplotlib. This came from http://old.nabble.com/calling-show%28%29-twice-in-a-row-td24276907.html
您好Ondrej,
Hi Ondrej,
我不确定在哪里可以找到好的 解释一下,但让我给 你一些提示.打算使用 每个程序仅显示一次.即 显示"应该是您的最后一行 脚本.如果你想互动 绘图您可能会考虑互动 模式(pyplot.ion-ioff),例如 下面的示例.
I'm not sure where to find a good explanation of that, but let me give you some hints. It is intended to use show only once per program. Namely 'show' should be the last line in your script. If you want interactive plotting you may consider interactive mode (pyplot.ion-ioff) like in the example below.
此外,还可以动态绘制所有图像 动画演示可能会有用.
Furthermore for dynamic plotting all animation demos might be useful.
也许您还想看看 http://matplotlib.sourceforge.net/users/shell.html
Maybe you want to have also a look at http://matplotlib.sourceforge.net/users/shell.html .
最诚挚的问候Matthias
best regards Matthias
所以看来这是一个没有记载的功能"(错误?).
So it seems it is an undocumented "feature" (bug?).
这是他的代码块:
from pylab import *
t = linspace(0.0, pi, 100)
x = cos(t)
y = sin(t)
ion() # turn on interactive mode
figure(0)
subplot(111, autoscale_on=False, xlim=(-1.2, 1.2), ylim=(-.2, 1.2))
point = plot([x[0]], [y[0]], marker='o', mfc='r', ms=3)
for j in arange(len(t)):
# reset x/y-data of point
setp(point[0], data=(x[j], y[j]))
draw() # redraw current figure
ioff() # turn off interactive mode
show()
因此,也许可以通过使用draw()获得所需的内容.我尚未测试此代码,我想知道它的行为.
So maybe by using draw() you can get what you want. I haven't tested this code, I'd like to know its behavior.
这篇关于matplotlib show()不能工作两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!