Skip to content Skip to sidebar Skip to footer

Tkinter And Pyplot Running Out Of Memory

I'm running a Tkinter script that updates a plot every 5 seconds. It calls the function that plots it every 5 seconds. After not that long python starts using a lot of memory, I ch

Solution 1:

It's not clear to me from your code how your plots are changing with time. So I don't have any specific suggestion for your existing code. However, here is a basic example of how to embed an animated matplotlib figure in a Tkinter app. Once you grok how it works, you should be able to adapt it to your situation.

import matplotlib.pyplot as plt
import numpy as np
import Tkinter as tk
import matplotlib.figure as mplfig
import matplotlib.backends.backend_tkagg as tkagg
pi = np.pi
sin = np.sin

classApp(object):
    def__init__(self, master):
        self.master = master
        self.fig = mplfig.Figure(figsize = (5, 4), dpi = 100)
        self.ax = self.fig.add_subplot(111)
        self.canvas = canvas = tkagg.FigureCanvasTkAgg(self.fig, master)
        canvas.get_tk_widget().pack(side = tk.TOP, fill = tk.BOTH, expand = 1)
        self.toolbar = toolbar = tkagg.NavigationToolbar2TkAgg(canvas, master)
        toolbar.update()
        self.update = self.animate().next
        master.after(10, self.update) 
        canvas.show()

    defanimate(self):
        x = np.linspace(0, 6*pi, 100)
        y = sin(x)
        line1, = self.ax.plot(x, y, 'r-')
        phase = 0whileTrue:
            phase += 0.1
            line1.set_ydata(sin(x + phase))
            newx = x+phase
            line1.set_xdata(newx)
            self.ax.set_xlim(newx.min(), newx.max())
            self.ax.relim()
            self.ax.autoscale_view(True, True, True) 
            self.fig.canvas.draw()
            self.master.after(10, self.update) 
            yielddefmain():
    root = tk.Tk()
    app = App(root)
    tk.mainloop()

if __name__ == '__main__':
    main()

The main idea here is that plt.plot should only be called once. It returns a Line2D object, line1. You can then manipulate the plot by calling line1.set_xdata and/or line1.set_ydata. This "technique" for animation comes from the Matplotlib Cookbook.

Technical note:

The generator function, animate was used here to allow the state of the plot to be saved and updated without having to save state information in instance attributes. Note that it is the generator function's next method (not the generator self.animate) which is being called repeatedly:

self.update = self.animate().next
    master.after(10, self.update) 

So we are advancing the plot frame-by-frame by calling the generator, self.animate()'s, next method.

Post a Comment for "Tkinter And Pyplot Running Out Of Memory"