在 tkinter 画布中嵌入来自 Arduino 的 Matplotlib 实时绘图数据 [英] Embedding Matplotlib live plot data from Arduino in tkinter canvas

查看:53
本文介绍了在 tkinter 画布中嵌入来自 Arduino 的 Matplotlib 实时绘图数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只用了几周 Python.我用 Matplotlib 绘制来自 Arduino 的数据没有问题.但是,该图显示为弹出窗口,我希望该图仅显示在我使用 tkinter 制作的 GUI 根窗口的画布中.我尝试了多种组合,但无法正常工作.如果我只是将绘图值添加到代码中,让我们说:

I've only been using Python for a couple of weeks. I have no problems plotting the data coming in from the Arduino with Matplotlib. However the plot shows up as a pop-window and I would like that plot to only show up in a canvas in the root window of the GUI I'm making with tkinter. I've tried multiple combinations of things and I can't get it to work. If I just add the plot values to the code, let's say:

a.plot([1, 2, 3, 4, 5], [2, 3, 4, 5, 6, 7])

它工作正常,所以我的主要问题是从 Arduino 获取数据时的 while 循环.我也尝试了 drawow 选项来更新绘图,但我得到了完全相同的结果.无论我做什么,我似乎都无法让情节停止显示为单独的窗口.

it works fine, so my main problem then is with the while loop when getting data from the Arduino. I've also tried the drawnow option to update the plot but I get the same exact result. Whatever I do I can't seem to get the plot from to stop showing up as a separate window.

后面带有主 GUI 窗口的绘图窗口:

Plot window with main GUI window in the back:

这是我正在使用的示例代码:

Here's the sample code that I'm using:

import serial
from tkinter import *
import numpy as np
from matplotlib import pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg


root = Tk()
root.geometry('1200x700+200+100')
root.title('This is my root window')
root.state('zoomed')
root.config(background='#fafafa')


yar = []
plt.ion()
style.use('ggplot')
fig = plt.figure(figsize=(14, 4.5), dpi=100)
ax1 = fig.add_subplot(1, 1, 1)
ser = serial.Serial('com3', 9600)

def animate(i):
    while True:
        ser.reset_input_buffer()
        data = ser.readline().decode("utf-8")
        data_array = data.split(',')
        yvalue = float(data_array[1])
        yar.append(yvalue)
        print(yvalue)
        plt.ylim(0, 100)
        ax1.plot(yar, 'r', marker='o')
        plt.pause(0.0001)


plotcanvas = FigureCanvasTkAgg(fig, root, animate)
plotcanvas.get_tk_widget().grid(column=1, row=1)
ani = animation.FuncAnimation(fig, animate, interval=1000, blit=True)
plotcanvas.show()

root.mainloop()

推荐答案

tk 的主循环会处理动画,因此你不应该使用 plt.ion() 或 plt.pause().

The main loop of tk will take care of the animation, you therefore shouldn't use plt.ion() or plt.pause().

动画函数将每隔 interval 秒调用一次.您不能在此函数中使用 while True 循环.

The animating function will be called every interval seconds. You cannot use a while True loop inside this function.

没有任何理由为 FigureCanvasTkAgg 提供动画功能.

There is no reason whatsoever to supply the animating function to the FigureCanvasTkAgg.

除非您知道自己在做什么,否则不要使用 blit=True.一秒钟的间隔,这无论如何是没有必要的.

Don't use blit=True unless you know what you're doing. With an interval of one second this is anyways not necessary.

更新线而不是在每个迭代步骤中重新绘制它.

Update the line instead of replotting it in every iteration step.

#import serial
from Tkinter import *
from matplotlib import pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg


root = Tk()
root.geometry('1200x700+200+100')
root.title('This is my root window')
root.state('zoomed')
root.config(background='#fafafa')

xar = []
yar = []

style.use('ggplot')
fig = plt.figure(figsize=(14, 4.5), dpi=100)
ax1 = fig.add_subplot(1, 1, 1)
ax1.set_ylim(0, 100)
line, = ax1.plot(xar, yar, 'r', marker='o')
#ser = serial.Serial('com3', 9600)

def animate(i):
    #ser.reset_input_buffer()
    #data = ser.readline().decode("utf-8")
    #data_array = data.split(',')
    #yvalue = float(data_array[1])
    yar.append(99-i)
    xar.append(i)
    line.set_data(xar, yar)
    ax1.set_xlim(0, i+1)


plotcanvas = FigureCanvasTkAgg(fig, root)
plotcanvas.get_tk_widget().grid(column=1, row=1)
ani = animation.FuncAnimation(fig, animate, interval=1000, blit=False)

root.mainloop()

这篇关于在 tkinter 画布中嵌入来自 Arduino 的 Matplotlib 实时绘图数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆