Как эффективно получить QLineSeries из Qchart в массивный массив?

Я пытаюсь получить QLineSeries из QChartс pointsVector() метод. Тем не менее, я потратил немало времени, чтобы получить эти LineSeries.

Для примера в этом коде:

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtChart import *
from PyQt5.QtWidgets import *
import sys
import numpy as np
from scipy import signal
import time

def series_to_polyline(xdata, ydata):
    """Convert series data to QPolygon(F) polyline

    This code is derived from PythonQwt's function named
    `qwt.plot_curve.series_to_polyline`"""
    size = len(xdata)
    polyline = QPolygonF(size)
    pointer = polyline.data()
    dtype, tinfo = np.float, np.finfo  # integers: = np.int, np.iinfo
    pointer.setsize(2*polyline.size()*tinfo(dtype).dtype.itemsize)
    memory = np.frombuffer(pointer, dtype)
    memory[:(size-1)*2+1:2] = xdata
    memory[1:(size-1)*2+2:2] = ydata
    return polyline

class pltlfp(QChartView):
    axischanged = pyqtSignal(float ,float ,float ,float)
    axisXchanged = pyqtSignal(float ,float , int)

    def __init__(self, parent=None):
        super(pltlfp, self).__init__(parent=parent)
        self.ncurves = 0
        self.chart = QChart()
        self.chart.legend().hide()
        self.setChart(self.chart)
        self.setRubberBand(QChartView.RectangleRubberBand)
        self.setRenderHint(QPainter.Antialiasing)
        self.chart.layout().setContentsMargins(0, 0, 0, 0)
        self.chart.setBackgroundRoundness(0)
        self.chart.setAnimationEasingCurve(QEasingCurve.Linear)
        print(self.chart.margins())
        self.chart.setMargins(QMargins())
        self.axisXlim =  []
        self.axisYlim =  []

        self.pos =  QPoint()
        self.begin =  QPoint()
        self.end=  QPoint()

    def emitaxischangesignal(self,pressed = 0 ):
        self.axisXchanged.emit(self.chart.axisX().min(),self.chart.axisX().max(),pressed)

    def mouseDoubleClickEvent(self,event):
        if (event.buttons() == Qt.LeftButton):
            # self.chart.zoomReset()
            self.setAxisinit()
            self.emitaxischangesignal()

    def mouseMoveEvent(self,event):
        if (event.buttons() == Qt.RightButton):
            x =  self.pos.x()-event.pos().x()
            y =  event.pos().y()-self.pos.y()
            self.chart.scroll(x,y)
            self.pos = event.pos()
            self.emitaxischangesignal()
        if (event.buttons() == Qt.LeftButton):
            super(pltlfp, self).mouseMoveEvent(event)
            # self.emitaxischangesignal()

    def mousePressEvent(self,event):
        if (event.button() == Qt.MidButton):
            self.emitaxischangesignal(1)
        if (event.button() == Qt.RightButton):
            self.pos = event.pos()
        if (event.button() == Qt.LeftButton):
            super(pltlfp, self).mousePressEvent(event)

    def mouseReleaseEvent(self, event):
        if (event.button() == Qt.LeftButton):
            super(pltlfp, self).mouseReleaseEvent(event)
            self.emitaxischangesignal()
            # self.chart.zoomIn(QRectF(self.begin,self.end))

    def set_title(self, title,xlabel=None,ylabel=None):
        self.chart.setTitle(title)
        self.chart.axisX().setTitleText(xlabel)
        self.chart.axisY().setTitleText(ylabel)

    def setneewaxis(self, x=[0,10], y=[0,10]):
        self.chart.axisX().setRange(x[0],x[1])
        self.chart.axisY().setRange(y[0],y[1])

    def add_data(self, xdata, ydata, color=None):
        curve = QLineSeries()
        pen = curve.pen()
        if color is not None:
            pen.setColor(color)
        pen.setWidthF(.1)
        curve.setPen(pen)
        curve.setUseOpenGL(True)
        curve.append(series_to_polyline(xdata, ydata))
        self.chart.addSeries(curve)
        self.chart.createDefaultAxes()
        self.axisXlim =  [self.chart.axisX().min(),self.chart.axisX().max()]
        self.axisYlim =  [self.chart.axisY().min(),self.chart.axisY().max()]
        self.ncurves += 1

    def replace_data(self, nb, xdata, ydata, color=None):
        self.chart.removeSeries(self.chart.series()[nb])
        self.add_data( xdata, ydata, color=color)

    def get_axis_data(self, nb):
        t0 = time.time()
        L = self.chart.series()[nb]
        print(1,time.time()-t0)
        t0 = time.time()
        data = L.pointsVector()
        print(2,time.time()-t0)
        t0 = time.time()
        data  = np.array([np.array([data[d].x(), data[d].y()])   for d in range(len(data))])
        print(3,time.time()-t0)
        t0 = time.time()
        dataX = data[:,0]
        print(4,time.time()-t0)
        t0 = time.time()
        dataY = data[:,1]
        print(5,time.time()-t0)
        t0 = time.time()
        axisXlim =  [self.chart.axisX().min(),self.chart.axisX().max()]
        print(6,time.time()-t0)
        t0 = time.time()
        idxstart=np.where(dataX>=axisXlim[0])[0][0]
        print(7,time.time()-t0)
        t0 = time.time()
        idxend = np.where(dataX<=axisXlim[1])[0][-1]
        print(8,time.time()-t0)
        t0 = time.time()
        dataY=dataY[idxstart:idxend]
        print(9,time.time()-t0)
        t0 = time.time()
        dataX=dataX[idxstart:idxend]
        print(10,time.time()-t0)
        t0 = time.time()
        return dataX,dataY


    def setAxis(self, xstart =0,xend =0, ystart =0, yend =0, ):
        self.chart.axisX().setRange(xstart,xend )
        # self.chart.axisY().setRange(ystart,yend)

    def setAxisinit(self):
        self.chart.axisX().setRange(self.axisXlim[0],self.axisXlim[1])
        self.chart.axisY().setRange(self.axisYlim[0],self.axisYlim[1])



class SurfViewer(QMainWindow):
    def __init__(self, parent=None,sig_dict=None, t=None):
        super(SurfViewer, self).__init__()
        self.parent = parent

        self.centralWidget= QWidget()
        self.setCentralWidget(self.centralWidget)
        # self.setFixedWidth(800)
        # self.setFixedHeight(800)

        #tab Model selection
        self.maplt1 = pltlfp()
        self.maplt1.add_data(t,sig_dict['ydata1'], color=Qt.red)
        self.maplt1.set_title("","Time [s]","ydata1")


        self.Vlayout = QVBoxLayout()
        self.Vlayout.addWidget(self.maplt1)
        self.centralWidget.setLayout(self.Vlayout)

        self.maplt1.axisXchanged.connect(self.signal_setaxis)

    @pyqtSlot(float ,float , int)
    def signal_setaxis(self, xstart,xend, pressed ):
        self.maplt1.setAxis(xstart,xend)
        if pressed == 1:
            dataX,dataY = self.maplt1.get_axis_data(0)



def main():
    app = QApplication(sys.argv)
    Fs = 100 * 1024
    npoints = 5 * Fs
    xdata1 = np.linspace(0., 5., npoints)
    ydata1 = np.sin(xdata1*2*3.1416*30)
    sig_dict = {'ydata1':ydata1 }
    ex = SurfViewer(app,sig_dict,xdata1)
    ex.setWindowTitle('window')
    ex.show()
    sys.exit(app.exec_( ))


if __name__ == '__main__':
    main()

Где я строю кривую с большим количеством точек. Я реализовал метод в pltlfpимя класса get_axis_data(self, nb) где я восстанавливаю LineSerie, который является сюжетом в этом классе. В этом методе я провел все время, делая data = L.pointsVector() а также data = np.array([np.array([data[d].x(), data[d].y()]) for d in range(len(data))]) Вот что я получаю из печати, которую я сделал в get_axis_data(self, nb) метод:

1 0.0
2 0.6440367698669434
3 1.9921140670776367
4 0.0
5 0.0
6 0.0
7 0.004000186920166016
8 0.0030002593994140625
9 0.0
10 0.0
Total  time 2.64315128326416

Я ищу несколько хороших советов, чтобы сократить это время. Для .pointsVector() Отмечу, что могу сделать лучше, но для другого это возможно.

Обновить

Я немного улучшил это

def get_axis_data(self, nb):
    L = self.chart.series()[nb]
    t0 = time.time()
    data = L.pointsVector()
    print(2,time.time()-t0)
    t0 = time.time()
    a = np.array([ [d.x(), d.y()]  for d in data])
    print(3,time.time()-t0)
    t0 = time.time()
    dataX = a[:,0]
    dataY = a[:,1]
    axisXlim =  [self.chart.axisX().min(),self.chart.axisX().max()]
    idxstart=np.where(dataX>=axisXlim[0])[0][0]
    idxend = np.where(dataX<=axisXlim[1])[0][-1]
    dataY=dataY[idxstart:idxend]
    dataX=dataX[idxstart:idxend]
    return dataX,dataY

что дает мне:

2 0.7390422821044922
3 0.9980571269989014

Но это все еще долго.

0 ответов

Другие вопросы по тегам