#python #timer #pyqt
#python #таймер #pyqt
Вопрос:
Я хотел бы использовать PyQt5 для анимации графика, чтобы вертикальная линия прокручивалась по моему рисунку с течением времени. Чтобы достичь этого, я начал изменять пример кода, приведенный в этом удобном руководстве по LearnPyQt. До сих пор мне удавалось построить единственную вертикальную линию по заданной пользователем оси абсцисс, используя:
self.canvas.axes.axvline(x=5)
Если бы я использовал for
цикл, я бы просто обновил x на основе индекса, но в этом случае я не могу понять, как обновить x на основе идентификатора таймера. Как я могу восстановить это значение и передать его в мою update_plot
функцию?
Вот мой код на данный момент:
import sys
import random
import matplotlib
matplotlib.use('Qt5Agg')
import pdb
from PyQt5 import QtCore, QtWidgets
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
class MplCanvas(FigureCanvas):
def __init__(self, parent=None, width=5, height=4, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
super(MplCanvas, self).__init__(fig)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.canvas = MplCanvas(self, width=5, height=4, dpi=100)
self.setCentralWidget(self.canvas)
self.timer_id = 0
n_data = 50
self.xdata = list(range(n_data))
self.ydata = [random.randint(0, 10) for i in range(n_data)]
self.update_plot()
self.show()
self.timer = QtCore.QTimer()
self.timer.setInterval(100)
self.timer.timeout.connect(self.update_plot)
self.timer.start()
def update_plot(self):
self.canvas.axes.plot(self.xdata, self.ydata, 'r')
self.canvas.axes.axvline(x=5)
self.canvas.draw()
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
app.exec_()
Ответ №1:
Если вы сохраняете ссылку на axvline (объект Line2D), то вы можете вызывать set_xdata
и увеличивать, self.timer_id
когда update_plot
вызывается перемещение линии вдоль рисунка.
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.canvas = MplCanvas(self, width=5, height=4, dpi=100)
self.setCentralWidget(self.canvas)
self.timer_id = 0
n_data = 50
self.xdata = list(range(n_data))
self.ydata = [random.randint(0, 10) for i in range(n_data)]
self.update_plot()
self.show()
self.timer = QtCore.QTimer()
self.timer.setInterval(100)
self.timer.timeout.connect(self.update_plot)
self.timer.start()
def update_plot(self):
if not self.timer_id:
self.canvas.axes.plot(self.xdata, self.ydata, 'r')
self.vline = self.canvas.axes.axvline(x=self.timer_id)
else:
self.vline.set_xdata(self.timer_id)
self.canvas.draw()
self.timer_id = 1
Комментарии:
1. Отлично! Большое спасибо, Алек! Я предполагаю, что я переосмыслил проблему: я думал о том, чтобы каким-то образом извлекать информацию о времени из
timer
метода, в то время как созданиеtimer_id
и увеличение его было самым простым способом. Еще раз спасибо!