[英]How can I update a matplotlib figure in a way that prevents xdata from being None?
I'm writing an application that periodically (approximately once per second) collects some data from a hardware device and displays it in a graph using matplotlib. 我正在编写一个应用程序,该应用程序定期(大约每秒一次)从硬件设备收集一些数据,并使用matplotlib将其显示在图形中。 The user will periodically click on the graph, and when that happens I need to know the x and y coordinates of the click, as measured in the graph's coordinate system.
用户将定期单击图形,当发生这种情况时,我需要知道图形的坐标系中测量的单击的x和y坐标。
This is easy enough to do: if canvas
is a FigureCanvas
instance, you can say 这很容易做到:如果
canvas
是FigureCanvas
实例,则可以说
canvas.mpl_connect('button_release_event', mouse_up_handler)
and define 并定义
def mouse_up_handler(event):
print('The user clicked at ({}, {})'.format(event.xdata, event.ydata))
to show the click coordinates in the graph's coordinate system. 以在图形的坐标系中显示点击坐标。 Occasionally, though, the user will click right as the graph is updating, and then
event.xdata
and .ydata
are None
. 但是,有时用户会在图形更新时单击鼠标右键,然后
event.xdata
和.ydata
为None
。 Right now I'm just discarding those clicks, but obviously it's pretty frustrating for the user when the application just ignores their clicks. 现在,我只是舍弃这些点击,但是当应用程序忽略他们的点击时,这显然让用户感到沮丧。
I've attached a full sample program so that you can see how I'm replacing the current graph with the new one. 我已经附上了完整的示例程序,以便您可以看到如何用新的图形替换当前的图形。 (If you run it and click on the graph repeatedly you'll see that the reported x coordinate is sometimes
None
.) Can I replace the figure's data in a way that never gives None
for the coordinates? (如果运行它并重复单击图形,您有时会看到报告的x坐标有时为
None
。)我可以用永远不会给出None
的方式替换图形的数据吗? I only want one set of data to be shown at a time. 我只希望一次显示一组数据。
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()
Something like: 就像是:
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()
to re-use the axes and Line2D
objects. 重用轴和
Line2D
对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.