在循环内调用图形的函数时,图形未绘制
Posted
技术标签:
【中文标题】在循环内调用图形的函数时,图形未绘制【英文标题】:Graph is not plotting when the function for the graph is called inside the loop 【发布时间】:2019-03-11 10:31:57 【问题描述】:我希望通过从文件中读取数据来将图表显示为幻灯片。首先,我希望绘制第一组数据,然后绘制下一组数据,依此类推。 我试过的是:
class MatplotlibWidget(QMainWindow):
def __init__(self):
---
self.playbutton.clicked.connect(self.drawGraph)
self.pausebutton.clicked.connect(self.pauseGraph)
----
def drawGraph(self):
f1 = open('TESTIP2.txt', 'r')
data = np.genfromtxt(f1)
m = np.size(data, 0)
n = np.size(data, 1)
x = data[:, 0].reshape(m, 1)
y = data[:, 1].reshape(m, 1)
iters = m // 4
current_iter=0
self.plotGraph(x,y,iters,current_iter)
def plotGraph(x,y,iters,current_iter):
for i in range(iters):
self.plotDraw(x[current_iter:current_iter+iters],y[current_iter:current_iter+iters])
current_iter=current_iter+iters
time.sleep(1)
def plotDraw(x,y)
self.MplWidget.canvas.axes.clear()
self.MplWidget.canvas.axes.plot(x,y)
self.MplWidget.canvas.axes.legend(('cosinus', 'sinus'), loc='upper right')
self.MplWidget.canvas.axes.set_title('Signal' )
self.MplWidget.canvas.draw()
在循环内部调用plotDraw 函数来显示每组数据,但它只显示最后一组数据。有没有办法在特定时间间隔后显示第一,第二等等。
【问题讨论】:
您能提供最小的可验证示例吗? (***.com/help/mcve)。 您是否尝试在 for 循环中包含plt.pause(1)
?
@Jack.Yes 我试过 plt.pause(1),但它不起作用。
@eyllanesc 。非常感谢您的帮助。
@eyllanesc。如何使用按钮或鼠标悬停或单击来暂停正在运行的循环,如果再次单击发生则应恢复
【参考方案1】:
最简单的方法是使用来自PyQt5
的QTimer
。这真的很容易使用:您指定一个应在超时后触发的函数,并指定时间间隔。使用以下代码,我每秒在 PyQt5
内的 Matplotlib 小部件中绘制随机数据。
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtCore import QTimer
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np
class M(QMainWindow):
def __init__(self):
super().__init__()
self.setGeometry(100,100,640,480)
self.Figure = Figure()
self.Canvas = FigureCanvas(self.Figure)
self.Canvas.setParent(self)
self.Canvas.move(0,0)
self.ax = self.Figure.add_subplot(111)
self.plotItem, = self.ax.plot([], [])
self.plot()
# Create timer
self.t = QTimer()
self.t.timeout.connect(self.plot) # specify function
self.t.start(1000) # 1 s
def plot(self):
"""plots random data and adjusts the x and y limits"""
x = np.linspace(0, np.random.randn()*100)
y = np.random.randn(50)
self.plotItem.set_xdata(x)
self.plotItem.set_ydata(y)
self.ax.set_ylim([y.min()-1, y.max()+1])
self.ax.set_xlim([x.min()-1, x.max()+1])
self.Canvas.draw() # update plot
if __name__ == '__main__':
app = QApplication([])
m = M()
m.show()
app.exec_()
上面的代码给你这个:
例如,您可以使用按钮触发self.t.stop()
以停止更新/循环,如果您想继续,您可以再次self.t.start(your_interval)
。
【讨论】:
你能帮我看看如何暂停图表以及向前和向后播放图表吗? 您需要将按钮与处理计时器的功能连接起来(例如,使用QTimer.IsActive()
方法检查计时器是否处于活动状态。如果它处于活动状态,那么您将停止计时器(参见我的答案)或者如果它已暂停,请以所需的时间间隔启动计时器(再次,请参阅我的答案)。如果将数据绘制为列表/数组的列表,则只需向前(递增计数器)或向后(递减计数器)。
好吧,没有看到任何your code,很难说它为什么不适合你。
您在问题中发布的代码?这不适合我的回答,也不是一个完全最小的工作示例(请参阅我最后评论的链接)。请尝试提供所有可以提供帮助的必要信息。我们不是来做 s.o. 的工作的。否则。以上是关于在循环内调用图形的函数时,图形未绘制的主要内容,如果未能解决你的问题,请参考以下文章
除非在Javascript中删除for循环,为什么interval函数不会执行
Java AWT 图形界面编程Canvas 组件中使用 Graphics 绘图 ① ( AWT 绘图线程 | Component 绘图函数 )