簡體   English   中英

我如何修改此代碼,以免每次都重新繪制圖形,matplotlib

[英]How can I modify this code so that I am not replotting my graph everytime, matplotlib

我正在從設備中獲取數據,並希望繪制其電壓,並將該圖嵌入到UI中 我在這里使用了示例: http : //matplotlib.org/examples/user_interfaces/embedding_in_qt4.html

這個示例工作正常,但是當我添加2個或更多圖形時,整個UI會變得非常慢(使用RPi3)並且CPU使用率會非常高。 我意識到這可能是因為圖形不斷被清除和重新繪制。

我的代碼如下所示:

class MyMplCanvas(FigureCanvas):
    def __init__(self, parent=None, width=5, height=2, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)

        self.compute_initial_figure()

        FigureCanvas.__init__(self, fig)
        self.setParent(parent)

        FigureCanvas.setSizePolicy(self,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

    def compute_initial_figure(self):
        pass

class MyDynamicMplCanvas(MyMplCanvas):

    def __init__(self, *args, **kwargs):
        MyMplCanvas.__init__(self, *args, **kwargs)

    def compute_initial_figure(self):
        self.axes.cla()

    def update_figure(self,voltage):
        self.axes.cla()
        self.axes.plot(np.linspace(0,len(voltage)-1,num = len(voltage)), voltage, 'b')  
        self.axes.set_xlabel("Time")
        self.draw()


class worker_thread(QThread):
... #worker thread stuff here

class Monitor(QtGui.QMainWindow):

    def __init__(self, parent = None):
        QtGui.QMainWindow.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.exit_button.clicked.connect(exit)
        self.ui.go_button.clicked.connect(self.start_monitoring)
        self.ui.print_button.clicked.connect(self.test_print)

        self.ac_graph = QtGui.QWidget(self)
        self.ac_1_graph = MyDynamicMplCanvas(self.ac_graph,width = 10, height =3 , dpi = 60)
        self.ui.mplvl.addWidget(self.ac_1_graph)
        self.ac_1_graph.axes.set_xlabel("Time")

        self.dc_graph = QtGui.QWidget(self)
        self.dc_2_graph = MyDynamicMplCanvas(self.dc_graph,width = 10, height =3 , dpi = 60)
        self.ui.mplvl_2.addWidget(self.dc_2_graph)      

        self.ac1_voltage_values = []
        self.ac1_current_values = []
        self.dc2_voltage_values = []

    def start_monitoring(self): 

        self.worker_thread = worker_thread()

        self.connect(self.worker_thread,SIGNAL('grid_done'),      self.update_ac_dc_info)

    def update_plot_values(self, y_value, y_list):
        y_list.append(y_value)
        if (len(y_list) == 61):
            del y_list[0]
        return y_list

    def update_ac_dc_info(self,grid_info):
        self.ac1_voltage_values = self.update_plot_values((grid_info['ac1_voltage']/10),self.ac1_voltage_values)
        self.ac_1_graph.update_figure(self.ac1_voltage_values)

本質上,當數據從我的設備返回時,我從worker_thread發出信號,該信號觸發我的UI在主線程以及繪圖中進行更新。 在這一點上,我如何讓matplotlib接受新的觀點,而無需重新介紹整個過程? 我閱讀的許多示例都使用了pyplot,我無法使用它,因為我需要將其嵌入到現有的UI中。

不必每次都有新數據時都清除軸,而只需重繪點線即可。 這樣可以節省一些時間。

class MyDynamicMplCanvas(MyMplCanvas):

    def __init__(self, *args, **kwargs):
        MyMplCanvas.__init__(self, *args, **kwargs)

    def compute_initial_figure(self):
        # empty plot
        self.line,  = self.axes.plot([],[], color="b")
        self.axes.set_xlabel("Time") # xlabel will not change over time

    def update_figure(self,voltage):

        self.line.set_data(np.linspace(0,len(voltage)-1,num = len(voltage)), voltage)  
        # now you need to take care of the axis limits yourself
        self.axes.set_xlim([0,len(voltage])
        self.draw()

僅更新最后一個新點有點棘手,因為繪圖由單個Line2D對象組成。 您可以選擇點圖,每次新數據到達時都可以在其中繪制一個新點。

ImportanceOfBeingErnest的方法效果很好。 要根據數據重新縮放軸,請執行以下操作:

self.axes.relim()
self.axes.autoscale_view(True,True,True)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM