Python 在tkinter画布中嵌入来自Arduino的Matplotlib实时打印数据

Python 在tkinter画布中嵌入来自Arduino的Matplotlib实时打印数据,python,canvas,matplotlib,tkinter,arduino,Python,Canvas,Matplotlib,Tkinter,Arduino,我使用Python才几个星期。我用Matplotlib绘制来自Arduino的数据没有问题。但是,该绘图显示为一个弹出窗口,我希望该绘图仅显示在我使用tkinter制作的GUI的根窗口的画布中。我尝试了多种组合,但都没能成功。如果我只是将绘图值添加到代码中,可以这样说: a.plot([1, 2, 3, 4, 5], [2, 3, 4, 5, 6, 7]) 它工作正常,所以我的主要问题是从Arduino获取数据时的while循环。我还尝试了drawnow选项来更新绘图,但得到了相同的精确结果。

我使用Python才几个星期。我用Matplotlib绘制来自Arduino的数据没有问题。但是,该绘图显示为一个弹出窗口,我希望该绘图仅显示在我使用tkinter制作的GUI的根窗口的画布中。我尝试了多种组合,但都没能成功。如果我只是将绘图值添加到代码中,可以这样说:

a.plot([1, 2, 3, 4, 5], [2, 3, 4, 5, 6, 7])
它工作正常,所以我的主要问题是从Arduino获取数据时的while循环。我还尝试了drawnow选项来更新绘图,但得到了相同的精确结果。无论我做什么,我似乎都无法让情节停止作为一个单独的窗口出现

背面有主GUI窗口的打印窗口:

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

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()

动画功能将每隔
时间间隔
秒调用一次。不能在此函数内使用
while True
循环

没有任何理由向
图CAVASTKAGG
提供动画功能

除非你知道自己在做什么,否则不要使用
blit=True
。以1秒为间隔,无论如何这是不必要的

更新行,而不是在每个迭代步骤中重新填充它

#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()

谢谢这很好用,正是我想要的。感谢其他提示,现在我对代码的工作原理有了更好的理解。