【问题标题】:Embedding Matplotlib live plot data from Arduino in tkinter canvas在 tkinter 画布中嵌入来自 Arduino 的 Matplotlib 实时绘图数据
【发布时间】:2017-06-30 17:38:06
【问题描述】:

我只用了几个星期的 Python。我用 Matplotlib 绘制来自 Arduino 的数据没有问题。但是,该图显示为一个弹出窗口,我希望该图仅显示在我使用 tkinter 制作的 GUI 的根窗口中的画布中。我已经尝试了多种组合,但我无法让它发挥作用。如果我只是将绘图值添加到代码中,假设:

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

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

绘图窗口和主 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()

【问题讨论】:

    标签: python canvas matplotlib tkinter arduino


    【解决方案1】:

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

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

    没有任何理由向FigureCanvasTkAgg 提供动画功能。

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

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

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

    【讨论】:

    • 谢谢!这很完美,正是我想要的。感谢其他提示,现在我对代码的工作原理有了更好的了解。
    猜你喜欢
    • 2015-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 2017-07-24
    • 2020-10-29
    相关资源
    最近更新 更多