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

Delosari
  • 677
  • 2
  • 17
  • 29
  • 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)``? – berna1111 Nov 11 '16 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.... – Delosari Nov 11 '16 at 15:45
  • I would try a refresh more like the one in [this answer](http://stackoverflow.com/questions/11270078/how-do-i-refresh-a-matplotlib-plot-in-a-tkinter-window), 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](http://stackoverflow.com/questions/31440167/placing-plot-on-tkinter-main-window-in-python). – berna1111 Nov 12 '16 at 00:10

0 Answers0