簡體   English   中英

如何以防止xdata變為None的方式更新matplotlib圖形?

[英]How can I update a matplotlib figure in a way that prevents xdata from being None?

我正在編寫一個應用程序,該應用程序定期(大約每秒一次)從硬件設備收集一些數據,並使用matplotlib將其顯示在圖形中。 用戶將定期單擊圖形,當發生這種情況時,我需要知道圖形的坐標系中測量的單擊的xy坐標。

這很容易做到:如果canvasFigureCanvas實例,則可以說

canvas.mpl_connect('button_release_event', mouse_up_handler)

並定義

def mouse_up_handler(event):
    print('The user clicked at ({}, {})'.format(event.xdata, event.ydata))

以在圖形的坐標系中顯示點擊坐標。 但是,有時用戶會在圖形更新時單擊鼠標右鍵,然后event.xdata.ydataNone 現在,我只是舍棄這些點擊,但是當應用程序忽略他們的點擊時,這顯然讓用戶感到沮喪。

我已經附上了完整的示例程序,以便您可以看到如何用新的圖形替換當前的圖形。 (如果運行它並重復單擊圖形,您有時會看到報告的x坐標有時為None 。)我可以用永遠不會給出None的方式替換圖形的數據嗎? 我只希望一次顯示一組數據。

范例程序

from __future__ import print_function
from math import exp
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg \
    as FigureCanvas
from matplotlib.figure import Figure
from random import normalvariate
from threading import Timer
from time import sleep
import wx

class GraphView(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        self.figure = Figure()
        canvas = FigureCanvas(self, -1, self.figure)
        canvas.mpl_connect('button_release_event', self.mouse_up_handler)

        self.axes = None

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(canvas, 1, wx.GROW)
        self.SetSizer(sizer)

        self.generate_new_data()

    def generate_new_data(self):
        x_values = range(16384)
        y_values = [exp(normalvariate(0, 10)) for _ in range(16384)]

        if self.axes is not None:
            self.figure.delaxes(self.axes)

        sleep(0.4)  # simulate some additional work being done with the data

        self.axes = self.figure.add_subplot(1, 1, 1)
        self.axes.set_yscale('log')
        self.axes.autoscale(enable=True)
        self.axes.set_xlim(x_values[0], x_values[-1])
        self.axes.plot(x_values, y_values, antialiased=False)

        self.figure.canvas.draw()

        Timer(1.0, self.generate_new_data).start()

    def mouse_up_handler(self, event):
        print('Click at x = {}'.format(event.xdata))


class GraphWindow(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent)
        graph_view = GraphView(self)


if __name__ == '__main__':
    app = wx.App(False)
    GraphWindow(None).Show()
    app.MainLoop()

就像是:

def __init__(self, parent):
    wx.Panel.__init__(self, parent)

    self.figure = Figure()
    canvas = FigureCanvas(self, -1, self.figure)
    canvas.mpl_connect('button_release_event', self.mouse_up_handler)

    # make axes
    self.ax = self.figure.add_subplot(1, 1, 1)
    # set up details
    self.ax.set_yscale('log')
    self.ax.autoscale(enable=True)
    self.ax.set_xlim(x_values[0], x_values[-1]) 
    # make the line
    self.ln, = self.ax.plot([], []) # add what ever parameters you want

    sizer = wx.BoxSizer(wx.VERTICAL)
    sizer.Add(canvas, 1, wx.GROW)
    self.SetSizer(sizer)

    self.generate_new_data()



def generate_new_data(self):
    x_values = range(16384)
    y_values = [exp(normalvariate(0, 10)) for _ in range(16384)]

    sleep(0.4)  # simulate some additional work being done with the data

    # update your existing line
    self.ln.set_data(x_values, y_values, antialiased=False)

    self.figure.canvas.draw()

    Timer(1.0, self.generate_new_data).start()

重用軸和Line2D對象。

暫無
暫無

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

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