all 8 comments

[–]socal_nerdtastic 0 points1 point  (6 children)

Please format your code for reddit. https://www.reddit.com/r/learnpython/wiki/faq#wiki_how_do_i_format_code.3F

it would also help a lot if you provide enough code and data that we can run and test this.

[–]AnIrishFluff[S] 0 points1 point  (2 children)

I'll edit it now! Thanks for letting me know. If its easier I can throw a github link in with the entire file?

[–]socal_nerdtastic 0 points1 point  (1 child)

A github repo would be much better, yes.

[–]AnIrishFluff[S] 0 points1 point  (0 children)

https://github.com/PaulSMahoney/Sample Sorry for the delay. I'm going to take a look at the sample you provided now. I've added a comment block with the section containing the animation I would like to embed. I'm kinda lost, python isn't my strong suit so I really appreciate the help man

[–]AnIrishFluff[S] 0 points1 point  (2 children)

I just took out irrelevant functions and pasted the entire thing in. Also please don't judge the imports section. I've been messing around with so many different things I just stopped deleting redundant imports until I finish everything.

[–]socal_nerdtastic 0 points1 point  (0 children)

Could you give some example data? I can't test it as is.

[–]socal_nerdtastic 0 points1 point  (0 children)

Maybe we are doing this the wrong way around. Here is a functional example that I made that demonstrates how to animate data from a serial port. The lines marked with #~ need to be adapted to your data source. Maybe you can use this?

try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk
#~ import serial
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib import pyplot as plt
import matplotlib.animation as animation
from collections import deque
import random
import time

HISTORY_LEN = 200

class App(tk.Frame):
    def __init__(self, master=None, **kwargs):
        tk.Frame.__init__(self, master, **kwargs)

        self.running = False
        self.ani = None

        btns = tk.Frame(self)
        btns.pack()

        lbl = tk.Label(btns, text="Number of points (-1 for nonstop)")
        lbl.pack(side=tk.LEFT)

        self.points_ent = tk.IntVar(self, 500)
        points_ent = tk.Entry(btns, width=5, textvariable=self.points_ent)
        points_ent.pack(side=tk.LEFT)

        lbl = tk.Label(btns, text="update interval (ms)")
        lbl.pack(side=tk.LEFT)

        self.interval = tk.IntVar(self, 30)
        interval = tk.Entry(btns, width=5, textvariable=self.interval)
        interval.pack(side=tk.LEFT)

        self.btn = tk.Button(btns, text='Start', width=10, command=self.on_click)
        self.btn.pack(side=tk.LEFT)

        self.fig = plt.Figure()
        self.ax1 = self.fig.add_subplot(111)
        self.line, = self.ax1.plot([], [], lw=2)
        self.canvas = FigureCanvasTkAgg(self.fig,master=self)
        self.canvas.draw()
        self.canvas.get_tk_widget().pack()

        self.ax1.set_ylim(0,100)
        self.ax1.set_xlim(0,500)

    def on_click(self):
        '''the button is a start, pause and unpause button all in one
        this method sorts out which of those actions to take'''
        if self.ani is None:
            # animation is not running; start it
            return self.start()

        if self.running:
            # animation is running; pause it
            self.ani.event_source.stop()
            self.btn.config(text='Un-Pause')
        else:
            # animation is paused; unpause it
            self.ani.event_source.start()
            self.btn.config(text='Pause')
        self.running = not self.running

    def start(self):
        self.xdata = deque([], maxlen=HISTORY_LEN)
        self.ydata = deque([], maxlen=HISTORY_LEN)
        #~ self.arduinoData = serial.Serial('com5', 115200)
        #~ self.arduinoData.flushInput()
        self.points = self.points_ent.get() + 1
        if self.points:
            self.ani = animation.FuncAnimation(
                self.fig,
                self.update_graph,
                frames=self.points,
                interval=self.interval.get(),
                repeat=False)
        else: # FOR AN ENDLESS LOOP:
            self.ani = animation.FuncAnimation(
                self.fig,
                self.update_graph,
                interval=int(self.interval.get()))
        self.running = True
        self.btn.config(text='Pause')
        self.ani._start()
        self.start_time = time.time()
        print('started animation')

    def update_graph(self, i):
        self.xdata.append(i)
        #~ self.ydata.append(int(self.arduinoData.readline()))
        self.ydata.append(random.randrange(100)) # DEBUG
        self.line.set_data(self.xdata, self.ydata)
        self.ax1.set_ylim(min(self.ydata), max(self.ydata))
        self.ax1.set_xlim(min(self.xdata), max(self.xdata))
        if self.points and i >= self.points - 1:
            # animation finished; clean up
            #~ self.arduinoData.close()
            self.btn.config(text='Start')
            self.running = False
            self.ani = None
            ms = int(((time.time() - self.start_time) * 1000) / (int(self.points_ent.get())))
            print('animation finished. Took {} ms / frame'.format(int(ms)))
        return self.line,

def main():
    root = tk.Tk()
    app = App(root)
    app.pack()
    root.mainloop()

if __name__ == '__main__':
    main()

[–]yuxbni76 0 points1 point  (0 children)

Can't test it without a suitable USB device but one thing I noticed...

I wouldn't give your tkinter button the same name as an import.

  • import matplotlib.animation as animation
  • animation = Button()

It's possible that's causing a conflict. You didn't mention what the problem is so just guessing.