scypy.signal.decimate()冻结GUI

2024-04-20 13:31:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我必须绘制大量样本(最多4e6个样本)的信号。我使用的是Python2.7、Qt4.8和pyqtgraph 0.9.10。你知道吗

我是这样做的:

  1. 生成信号并抽取它们(在单独的QThread中)
  2. 绘制信号并调用setDownsample()和clipToView()(pyqtgraph的方法)

问题是当QThread for decimate计算时,GUI会冻结。这是我的密码:

class TestDecimate(QDialog):

    def __init__(self, parent=None):
        super(TestDecimate, self).__init__(parent)

        self.decimate_thread = GenerateBigPlotThread()

        layout = QGridLayout()

        graph_widget = pg.GraphicsLayoutWidget()
        graph_layout = graph_widget.addLayout()

        self.p = graph_layout.addPlot(title="Plot 2", col=1, row=2)
        self.curve1 = self.p.plot([], pen=(255, 0, 0))
        self.curve2 = self.p.plot([], pen=(255, 255, 0))
        self.curve3 = self.p.plot([], pen=(255, 0, 255))
        self.curve4 = self.p.plot([], pen=(0, 0, 255))
        self.p.showGrid(True, True, 0.3)

        self.legend = pg.LegendItem(offset=(-10,10))
        self.legend.addItem(self.curve1, name="Test")
        self.legend.addItem(self.curve2, name="Test1")
        self.legend.addItem(self.curve3, name="Test2")
        self.legend.addItem(self.curve4, name="Test3")
        self.legend.setParentItem(self.p.getViewBox())

        self.start_pb = QPushButton("Generate")

        layout.addWidget(graph_widget, 1, 1)
        layout.addWidget(self.start_pb, 2, 1)

        self.setLayout(layout)

        self.start_pb.clicked.connect(self.start_thread_for_decimate)
        self.decimate_thread.newData.connect(self.set_data)

    def set_data(self, y, z, n, m):
        print "Plotting"
        self.curve1.setData(y)
        self.curve2.setData(z)
        self.curve3.setData(n)
        self.curve4.setData(m)

        self.p.setDownsampling(ds=True, auto=True, mode='peak')
        self.p.setClipToView(clip=True)
        self.p.getViewBox().enableAutoRange(axis=ViewBox.XYAxes)
        print "Plotting done"


    def start_thread_for_decimate(self):
        self.decimate_thread.start()

if __name__ == "__main__":
     app = QApplication(sys.argv)
     main = TestDecimate()
     main.show()
     sys.exit(app.exec_())

计算和抽取线程:

class GenerateBigPlotThread(QThread):

    newData = QtCore.pyqtSignal("PyQt_PyObject","PyQt_PyObject","PyQt_PyObject","PyQt_PyObject")

    def __init__(self,*arg,**kwargs):
        super(GenerateBigPlotThread, self).__init__(*arg,**kwargs)

    def run(self):

        self.num_points = 4e6

        x = np.arange(self.num_points)
        y = np.sin(3.14159 * x * 10/self.num_points)
        z = np.cos(3.14159 * x * 10/self.num_points)
        n = np.sin(3.14159 * x * 5/self.num_points)
        m = np.cos(3.14159 * x * 5/self.num_points)
        print "Decimate"
        y = decimate(y, 4, ftype='fir')
        z = decimate(z, 4, ftype='fir')
        n = decimate(n, 4, ftype='fir')
        m = decimate(m, 4, ftype='fir')
        print "Done!"

        self.newData.emit(y, z, n, m)

当线程启动时,查看问题的最佳方法是移动图例。 我也试过了scipy.signal.resample重采样(4e6个样本到1e6个样本)而不是抽取,出现相同的问题。 有人能告诉我这种行为的原因吗?你知道吗


Tags: nameselftrueinitdefnpthreadstart
1条回答
网友
1楼 · 发布于 2024-04-20 13:31:39

问题出在scipy版本中。我有scipy0.13.2,升级到0.17.0后,问题似乎得到了解决。尽管如此,我还是想知道为什么这样的事情一开始是可能的。你知道吗

相关问题 更多 >