问题
I am trying to write a Python GUI and I need to do a live plot. I currently have a program that receives data from a machine I am using and I want to be able to plot the values the machine outputs as I receive them. I have been researching and from what I have found so far, it doesn't seem to me like tkinter or any library can do this in a GUI. Does anyone know whether and how tkinter can do this or if there is another library that is capable of doing such a live plot?
Also, how would I go about writing the data that I gather to a file as I receive the data?
Thanks in advance for your help.
回答1:
It looks like you get the data by polling, which means you don't need threads or multiple processes. Simply poll the device at your preferred interface and plot a single point.
Here's an example with some simulated data to illustrate the general idea. It updates the screen every 100ms.
import Tkinter as tk
import random
class ServoDrive(object):
# simulate values
def getVelocity(self): return random.randint(0,50)
def getTorque(self): return random.randint(50,100)
class Example(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.servo = ServoDrive()
self.canvas = tk.Canvas(self, background="black")
self.canvas.pack(side="top", fill="both", expand=True)
# create lines for velocity and torque
self.velocity_line = self.canvas.create_line(0,0,0,0, fill="red")
self.torque_line = self.canvas.create_line(0,0,0,0, fill="blue")
# start the update process
self.update_plot()
def update_plot(self):
v = self.servo.getVelocity()
t = self.servo.getTorque()
self.add_point(self.velocity_line, v)
self.add_point(self.torque_line, t)
self.canvas.xview_moveto(1.0)
self.after(100, self.update_plot)
def add_point(self, line, y):
coords = self.canvas.coords(line)
x = coords[-2] + 1
coords.append(x)
coords.append(y)
coords = coords[-200:] # keep # of points to a manageable size
self.canvas.coords(line, *coords)
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(side="top", fill="both", expand=True)
root.mainloop()
回答2:
As far as I understand it, it can be done with tkinter/Qt/wxpython etc. You just have to make use of mutlithreading
and multiprocessing
.
There may be a simpler way to do it with another module, but I am unaware of it.
I have been looking into something similar to this problem for a long time as well, and it appears that it is a constant issue among this community.
Here are some threads which talk about the issue:
How do I refresh a matplotlib plot in a Tkinter window?
How do I update a matplotlib figure while fitting a function?
来源:https://stackoverflow.com/questions/15736393/live-plot-in-python-gui