PyQtGraph: проблема с циклическим отображением срезов данных - PullRequest
3 голосов
/ 16 июня 2020

У меня есть класс python, который генерирует массив numpy размером 10000 и выполняет над ним некоторые вычисления. Класс имеет два метода построения графиков, и оба используют pyqtgraph

  • Отображение всех данных
  • Построение сегментов данных по одному (200 выборок)

Мне было интересно, как я могу l oop просматривать сегменты данных (200 выборок за раз) и показывать обработанные данные пользователю и ждать, пока пользователь не нажмет любую клавишу, прежде чем строить следующие 200 выборок?

Я хотел бы иметь возможность обновлять график, не закрывая окно Qt, чтобы добиться более эффективной производительности, просто обновляя содержимое уже построенного объекта.

import numpy as np
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg

class testqt:

    def __init__(self):
        self.data = np.random.randn(10000) # for the sake of providing a MWE
        self.do_some_processing()

    def do_some_processing(self):
        self.data_processed = 2*self.data

    def plot_entire_processed_data(self):
        # Plot the entire processed data
        win = pg.GraphicsLayoutWidget(show=True)
        p = win.addPlot()
        curve_data = p.plot(self.data_processed)
        QtGui.QApplication.instance().exec_()

    def plot_processed_data_every_200(self):
        # animate the processed data in segments of 200 samples
        win = pg.GraphicsLayoutWidget(show=True)
        p = win.addPlot()
        curve_data = p.plot(self.data_processed[:200])

        for i in range(200, len(self.data_processed), 200):
            curve_data.setData(self.data_processed[i:i+200])
            # How can I pause here and use keyboard to move to the next 200 samples?
            # I would like to be able to visually evaluate each segment first and then 
            # press any key to see the next segment


        QtGui.QApplication.instance().exec_() # unfortunately, this only plot the last 200 samples


a = testqt()
a.plot_entire_processed_data()
a.plot_processed_data_every_200()

Я был бы признателен за любую помощь или подсказка.

1 Ответ

2 голосов
/ 16 июня 2020

Для обнаружения события клавиатуры существует несколько опций в зависимости от конкретной c цели:

  • Если вы хотите обнаружить нажатие любой клавиши, когда фокус находится в виджете , затем просто переопределите метод keyPressEvent окна.

  • Если вы хотите обнаруживать нажатие любой клавиши, даже если в окне нет клавиши, тогда вы должны использовать библиотеки ОС, в python, к счастью, есть оболочки, такие как pyinput, keyboard и т. д. c.

С другой стороны, logi c предназначен для получения фрагментов данных, поэтому для этого просто используйте функцию генератора.

Рассматривая первый случай, решение:

import numpy as np
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg


def iter_by_step(data, step):
    for i in range(0, len(data), step):
        yield data[i : i + step]


class GraphicsLayoutWidget(pg.GraphicsLayoutWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.data = np.random.randn(10000)
        self.iter = None

        curve = self.addPlot()
        self.p = curve.plot()

    def do_some_processing(self):
        self.data_processed = 2 * self.data
        self.iter = iter_by_step(self.data_processed, 200)
        self.plot_processed_data_every_200()

    def keyPressEvent(self, event):
        super().keyPressEvent(event)
        if self.iter is not None:
            self.plot_processed_data_every_200()

    def plot_processed_data_every_200(self):
        try:
            data = next(self.iter)
        except StopIteration:
            pass
        else:
            self.p.setData(data)


if __name__ == "__main__":

    w = GraphicsLayoutWidget()
    w.show()
    w.do_some_processing()

    QtGui.QApplication.instance().exec_()
...