我有一个奇怪的问题,matplotlib。如果我运行这个程序,我可以打开和关闭几次相同的数字。
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函数代码,它只会在第一次打开图形,在其他事件中,它会进入函数,但不会显示图形:
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)
型
这个小部件是动画绘图所需的,当实验完成时,如果我点击绘图,它应该会出现一个图形,只会在第一次出现。
你有什么线索吗?
非常感谢
6条答案
按热度按时间rxztt3cl1#
在代码的开头,通过
plt.ion()
启用交互模式。ujv3wf0j2#
我有新的信息,这是一个谷歌搜索出现
这是matplotlib的作者写的,来自http://old.nabble.com/calling-show%28%29-twice-in-a-row-td24276907.html
你好Ondrej,
我不知道在哪里可以找到一个很好的解释,但让我给你给予一些提示。它旨在每个程序只使用一次show。也就是说,“show”应该是你脚本中的最后一行。如果你想要交互式绘图,你可以考虑交互式模式(pyplot.ion-ioff),如下面的例子。
此外,对于动态绘图,所有动画演示可能都很有用。
你也可以看看http://matplotlib.sourceforge.net/users/shell.html。
最好的问候马蒂亚斯
因此,它似乎是一个未记录的“功能”(bug?)。
Edit:这里是他的代码块:
字符串
所以也许通过使用draw()你可以得到你想要的。我还没有测试过这段代码,我想知道它的行为。
dkqlctbz3#
我在第一次使用show()时也遇到了同样的问题。你还在使用0.99.3版本吗?我最近解决了这个问题,如果你仍然对改变show()的行为感兴趣,试试这个:
我注意到matplotlib下载站点的“新增功能”部分有一段标题为“multiple calls to show supported”的内容。
一个长期存在的要求是支持对show()的多个调用。这很困难,因为很难在操作系统、用户界面工具包和版本之间获得一致的行为。Eric Firing在使show在后端之间合理化方面做了很多工作,使用所需的行为使show引发所有新创建的图形并阻止执行,直到它们被关闭。重复调用show应该引发新创建的图形。Eric已经对他可以访问的用户界面工具包、版本和平台进行了大量测试,但是不可能全部测试,所以请向邮件列表和错误跟踪报告问题。
这是1.0.1版的“新特性”,在写这篇文章的时候,新立得的版本还是0.99.3。我可以从1.0.1版的源代码下载和构建。我还需要额外的软件包来满足依赖性,比如
libfreetype6-dev tk-dev tk8.5-dev tcl8.5-dev python-gtk2-dev
;你的里程可能会有所不同。现在我有了
matplotlib.__version__ == 1.0.1
,下面的代码可以按照我所期望的方式工作:字符串
cgfeq70w4#
字符串
试试看:
型
ndh0cuux5#
我解决这个问题的方法是永远不要调用
close
。我很确定你可以在PyQt中控制小部件的透明度。你可以尝试使用Qt而不是matplotlib来控制可见性。我相信其他对matplotlib了解更多的人可以给予比这个更好的答案:D
7kjnsjlb6#
可以通过以下方式创建地物示例:
字符串
并通过操作这个图来绘制你的东西。你可以随时使用
fig.show()
来显示你的图。