python - 在 tkinter Canvas 中嵌入来自 Arduino 的 Matplotlib 实时绘图数据

标签 python canvas matplotlib tkinter arduino

我使用 Python 才几周时间。我可以毫无问题地使用 Matplotlib 绘制来自 Arduino 的数据。然而,该图显示为一个弹出窗口,我希望该图仅显示在我使用 tkinter 制作的 GUI 的根窗口中的 Canvas 中。我尝试了多种组合,但无法正常工作。如果我只是将绘图值添加到代码中,比方说:

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

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

绘图窗口和后面的主 GUI 窗口:

Plot window with main GUI window in the back

这是我使用的示例代码:

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

动画函数将每 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()

关于python - 在 tkinter Canvas 中嵌入来自 Arduino 的 Matplotlib 实时绘图数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42192133/

相关文章:

javascript - 如何考虑多边形的 Angular

python - Matplotlib Figsize 不受尊重

arrays - python - Matplotlib 3D 输入格式化 Z(相关)值

javascript - 如何在 Canvas 中实现英雄选择?

javascript - 我正在 html 5 Canvas 上工作并尝试在其上绘制圆圈,但是当我尝试使用循环时所有内容都消失了

python - 如何增加 Seaborn Line 的线条粗细

python - 如何获得非阻塞套接字连接()?

python - PhantomJS 1.8 在 python 上使用 Selenium。如何屏蔽图片?

python - 为什么硬编码这个列表比计算它慢?

python,将列表转换为相似的子列表