0

I have a small interface which loads data into a matplotlib figure. I would like to be able to load pickles which contain previously made plots but somehow I cannot make it work.

This is one of the examples from matplotlib to embed a plot within tkinter:

import sys
import pickle
import matplotlib
from numpy import arange, sin, pi, cos
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
if sys.version_info[0] < 3:
    import Tkinter as Tk
else:
    import tkinter as Tk

def restore_from_pickle(pickle_address, fig):
    fig.clear()
    with open(pickle_address, 'rb') as fid:
        fig = pickle.load(fid)
    return

def _quit():
    root.quit()
    root.destroy()

def on_key_event(event):
    print('you pressed %s' % event.key)
    key_press_handler(event, canvas, toolbar)

matplotlib.use('TkAgg')
root = Tk.Tk()
root.wm_title("Embedding in TK")

f = Figure(figsize=(5, 4), dpi=100)
t = arange(0.0, 3.0, 0.01)

#Plot to store
a = f.add_subplot(111)
s = sin(2*pi*t)
a.plot(t, s)

#Saving to pickle
with open('figure_pickle', 'wb') as fid:
    pickle.dump(f, fid)

#Initial plot display
f.clear()
a = f.add_subplot(111)
s = cos(2*pi*t)
a.plot(t, s)

# a tk.DrawingArea
canvas = FigureCanvasTkAgg(f, master=root)
canvas.show()
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

toolbar = NavigationToolbar2TkAgg(canvas, root)
toolbar.update()
canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)

canvas.mpl_connect('key_press_event', on_key_event)

button = Tk.Button(master=root, text='f(sin)', command=restore_from_pickle('figure_pickle', f))
#button = Tk.Button(master=root, text='Quit', command=_quit)
button.pack(side=Tk.BOTTOM)

Tk.mainloop() 

This produces something like:

Original image

If you press the button it closes the window. I modified it so it saves a pickle containing one figure and the button now loads this image. However, when I run it:

Implementing pickle

The original plot is not drawn and neither the one in the pickle...

What is happening?

Thanks for any advice

3
  • If I had to guess I would say it has something to do with the fig = pickle.load(fid) line - are you sure that pickle.load(...) returns a figure object? Shouldn't you be saving the data that was plotted, and then loading it and plotting it in the existing figure? Or, if pickle.load(...) really returns a figure object (as a figure object was indeed saved), don't you have to associate it again to the root, as you did with canvas = FigureCanvasTkAgg(f, master=root)? Commented Nov 11, 2016 at 14:51
  • Thank you very much for the comment. Yes I believe you point in the right direction. However, this "pickling" technique works for me when I am not working withing a tkinter GUI... However, I cannot manage to make it work in this case.... Commented Nov 11, 2016 at 15:45
  • I would try a refresh more like the one in this answer, where he imports the data as an x and y arrays and plots them on the existing line. I reckon you would loose axis information, so if you really want to import a complete figure try and repeat the whole association of the imported figure with the canvas, like here. Commented Nov 12, 2016 at 0:10

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.