2017-02-12 13 views
3

Я использую Python только пару недель. У меня нет проблем с составлением графика данных, поступающих из Arduino с Matplotlib. Однако сюжет отображается как всплывающее окно, и я хотел бы, чтобы этот сюжет отображался только на холсте в корневом окне графического интерфейса, который я создаю с помощью tkinter. Я пробовал несколько комбинаций вещей, и я не могу заставить его работать. Если бы я просто добавить значения графика в коде, скажем:Вложение Matplotlib данные в реальном времени из Arduino в холст tkinter

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

он отлично работает, так что моя основная проблема тогда с петлей в то время как при получении данных из Arduino. Я также попробовал вариант drawow для обновления сюжета, но я получаю тот же точный результат. Независимо от того, что я делаю, я, похоже, не могу заставить сюжет прекратить показываться как отдельное окно.

[Окно Участка с главным окном графического интерфейса в задней части] [1]

Вот пример код, который я использую:

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

ответ

2

Основной цикл Ок будет позаботьтесь об анимации, поэтому вы не должны использовать 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) 
plotcanvas.show() 

root.mainloop() 
+0

Спасибо! Это работает отлично, именно то, что я искал. Спасибо за другие советы, теперь я лучше понимаю, как работает код. –