эффективно отображать большие наборы данных с помощью pyqtgraph

Я пытаюсь создать матрицу точечных диаграмм и гистограмм с помощью pyqtgraph. Входные данные (значения x и y) для каждой диаграммы рассеяния представляют собой пустые массивы длиной более 1 000 000. Создание этих графиков занимает очень много времени (> 1 минуты для матрицы графика 2x2) (на самом деле matplotlib быстрее генерирует те же графики). Можете ли вы указать, что я могу сделать, чтобы ускорить процесс? Ниже приведен код, который я использую.

Спасибо.

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

def scatter_matrix(data, cols):
    pg.setConfigOption('background', 'w')
    pg.setConfigOption('foreground', 'k')
    now = pg.ptime.time()

    app = QtGui.QApplication([])

    win = pg.GraphicsWindow(title="Scater Plot Matrix")
    win.resize(800,600)

    for i, col_i in enumerate(cols):
        for j, col_j in enumerate(cols):
            x = data[col_i]
            y = data[col_j]
            if i == j:
                current_plot = win.addPlot(title="Histogram")
                y,x = np.histogram(x, bins=100)
                curve = pg.PlotCurveItem(x, y, stepMode=True, fillLevel=0, brush=(0, 0, 255, 80))
                current_plot.addItem(curve)
            else:
                current_plot = win.addPlot(title="Scatter plot")
                current_plot.plot(x, y, pen=None, symbol='t', symbolPen=None, symbolSize=10, symbolBrush=(100, 100, 255, 50))
                current_plot.setLabel('left', "{}".format(col_i), units='')
                current_plot.setLabel('bottom', "{}".format(col_j), units='')
                current_plot.setLogMode(x=False, y=False)
        win.nextRow()
    ## Start Qt event loop unless running in interactive mode or using pyside.
    import sys
    print "Plot time: %0.2f sec" % (pg.ptime.time()-now)
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        app.exec_()

data = {}
for key in ['a','b']:
    data[key] = np.random.normal(size=(1000000), scale=1e-5)

scatter_matrix(data,['a','b'])

После долгих поисков в Интернете я в конечном итоге попробовал графическую библиотеку на основе графического процессора, galry. В результате скорость увеличилась более чем в 100 раз! Ниже приведен код. Независимо от этого, я все же хотел бы знать, есть ли способы ускорить построение графика с помощью pyqtgraph.

import numpy as np
from galry import *
import time

class MyPaintManager(PlotPaintManager):
    def initialize(self):
        if self.parent.visual == BarVisual:
            self.add_visual(self.parent.visual, self.parent.x, primitive_type= self.parent.plot_type, color='b')
        elif self.parent.visual == PlotVisual:
            self.add_visual(self.parent.visual, x=self.parent.x, y=self.parent.y, primitive_type= self.parent.plot_type, color='b')

class MyWidget(GalryWidget):
    def initialize(self, x, y, visual, title=None, plot_type=None):
        self.activate_grid = True
        self.show_grid = True

        self.x = x
        self.y = y
        self.visual = visual
        self.plot_type = plot_type
        self.title = title

        self.set_bindings(PlotBindings)
        self.set_companion_classes(
            paint_manager=MyPaintManager,
            interaction_manager=PlotInteractionManager,)
        self.initialize_companion_classes()

def scatter_matrix(df, cols):
    now = time.time()

    class Window(QtGui.QWidget):
        def __init__(self):
            super(Window, self).__init__()
            self.initUI()

        def initUI(self):
            vbox = QtGui.QGridLayout()
            self.setLayout(vbox)
            self.setGeometry(300, 300, 600, 600)
            for i, col_i in enumerate(cols):
                for j, col_j in enumerate(cols):
                    x = df[col_i]
                    y = df[col_j]
                    if i == j:
                        y,x = np.histogram(x, bins=100)
                        vbox.addWidget(MyWidget(x=y,y=y, visual = BarVisual, title='{}_vs_{}'.format(col_i, col_j)), i, j)
                    else:
                        vbox.addWidget(MyWidget(x=x,y=y, visual = PlotVisual, title='{}_vs_{}'.format(col_i, col_j), plot_type='POINTS'), i, j)

            print "Plot time: %0.2f sec" % (time.time()-now)
            self.show()

    show_window(Window)

if __name__ == '__main__':
    data = {}
    for key in ['a','b']:
        data[key] = np.random.normal(size=(1000000), scale=1e-5)

    scatter_matrix(data,['a','b'])

person user3520133    schedule 10.04.2014    source источник


Ответы (1)


Ваш код выглядит нормально. В зависимости от вашей системы эффективность диаграммы рассеяния снижается примерно на 10–100 000 точек для pyqtgraph. Если вы действительно хотите продолжать использовать pyqtgraph, все, что я могу порекомендовать, — это подвыборка ваших данных в 10-100 раз.

Объем данных, которые вы хотите визуализировать, почти требует ускорения графического процессора, поэтому Galry — хороший инструмент для использования здесь. К вашему сведению, разработчики pyqtgraph, Galry и нескольких других графических библиотек Python вместе работают над VisPy, который не совсем готов к использованию, но в будущем должен стать очень хорошим вариантом. PyQtGraph также будет использовать VisPy для обеспечения ускорения графического процессора в будущем.

person Luke    schedule 12.04.2014
comment
Спасибо за предоставление этой информации. Я столкнулся с VisPy и понял, что он все еще находится на ранней стадии разработки. Как только этот проект созреет, я попробую. - person user3520133; 14.04.2014
comment
@Luke У PyQtGraph теперь есть ускорение графического процессора? - person eric; 20.07.2021
comment
Не так, как я предсказывал выше, но недавно произошли некоторые значительные улучшения производительности (я полагаю, что они используют как графический процессор, так и numba) для ускорения графического конвейера. Я рекомендую протестировать последнюю версию с github, чтобы убедиться, что она соответствует вашим потребностям. - person Luke; 22.07.2021