Store and reload matplotlib.pyplot object
Question:
I work in an psudo-operational environment where we make new imagery on receipt of data. Sometimes when new data comes in, we need to re-open an image and update that image in order to create composites, add overlays, etc. In addition to adding to the image, this requires modification of titles, legends, etc.
Is there something built into matplotlib that would let me store and reload my matplotlib.pyplot object for later use? It would need to maintain access to all associated objects including figures, lines, legends, etc. Maybe pickle is what I’m looking for, but I doubt it.
Answers:
Did you try the pickle module? It serialises an object, dumps it to a file, and can reload it from the file later.
I produced figures for a number of papers using matplotlib. Rather than thinking of saving the figure (as in MATLAB), I would write a script that plotted the data then formatted and saved the figure. In cases where I wanted to keep a local copy of the data (especially if I wanted to be able to play with it again) I found numpy.savez() and numpy.load() to be very useful.
At first I missed the shrink-wrapped feel of saving a figure in MATLAB, but after a while I have come to prefer this approach because it includes the data in a format that is available for further analysis.
As of 1.2 matplotlib ships with experimental pickling support. If you come across any issues with it, please let us know on the mpl mailing list or by opening an issue on github.com/matplotlib/matplotlib
HTH
EDIT: Added a simple example
import matplotlib.pyplot as plt
import numpy as np
import pickle
ax = plt.subplot(111)
x = np.linspace(0, 10)
y = np.exp(x)
plt.plot(x, y)
pickle.dump(ax, file('myplot.pickle', 'w'))
Then in a separate session:
import matplotlib.pyplot as plt
import pickle
ax = pickle.load(file('myplot.pickle'))
plt.show()
A small modification to Pelson’s answer for people working on a Jupyterhub
Use %matplotlib notebook
before loading the pickle. Using %matplotlib inline
did not work for me in either jupyterhub or jupyter notebook. and gives a traceback ending in
AttributeError: ‘module’ object has no attribute ‘new_figure_manager_given_figure’.
import matplotlib.pyplot as plt
import numpy as np
import pickle
%matplotlib notebook
ax = plt.subplot(111)
x = np.linspace(0, 10)
y = np.exp(x)
plt.plot(x, y)
with open('myplot.pkl','wb') as fid:
pickle.dump(ax, fid)
Then in a separate session:
import matplotlib.pyplot as plt
import pickle
%matplotlib notebook
with open('myplot.pkl','rb') as fid:
ax = pickle.load(fid)
plt.show()
Tested in jupyter notebook.
import matplotlib.pyplot as plt
import numpy as np
import pickle
fig, axes = plt.subplots(figsize=(20, 5),nrows=1, ncols=2)
x,y = np.arange(10), np.random.random(10)
axes[0].plot(x,y)
axes[1].plot(x,y)
plt.show()
# myfname = input("Save figure? [enter filename]: ")
myfname = 'test'
if (myfname!=''):
fig.savefig(f'./{myfname}.png')
print(f'file saved to ./{myfname}.png')
with open(f'./{myfname}.png.pkl','wb') as fid:
pickle.dump(fig, fid)
print(f'pickled to ./{myfname}.png.pkl')
###################################
####### in a separate session
myfname = 'test'
with open(f'./{myfname}.png.pkl', 'rb') as fh:
fig_loaded = pickle.load(fh)
print(fig_loaded.axes[0].lines[0].get_data()) # get data
fig_loaded # show fig
I work in an psudo-operational environment where we make new imagery on receipt of data. Sometimes when new data comes in, we need to re-open an image and update that image in order to create composites, add overlays, etc. In addition to adding to the image, this requires modification of titles, legends, etc.
Is there something built into matplotlib that would let me store and reload my matplotlib.pyplot object for later use? It would need to maintain access to all associated objects including figures, lines, legends, etc. Maybe pickle is what I’m looking for, but I doubt it.
Did you try the pickle module? It serialises an object, dumps it to a file, and can reload it from the file later.
I produced figures for a number of papers using matplotlib. Rather than thinking of saving the figure (as in MATLAB), I would write a script that plotted the data then formatted and saved the figure. In cases where I wanted to keep a local copy of the data (especially if I wanted to be able to play with it again) I found numpy.savez() and numpy.load() to be very useful.
At first I missed the shrink-wrapped feel of saving a figure in MATLAB, but after a while I have come to prefer this approach because it includes the data in a format that is available for further analysis.
As of 1.2 matplotlib ships with experimental pickling support. If you come across any issues with it, please let us know on the mpl mailing list or by opening an issue on github.com/matplotlib/matplotlib
HTH
EDIT: Added a simple example
import matplotlib.pyplot as plt
import numpy as np
import pickle
ax = plt.subplot(111)
x = np.linspace(0, 10)
y = np.exp(x)
plt.plot(x, y)
pickle.dump(ax, file('myplot.pickle', 'w'))
Then in a separate session:
import matplotlib.pyplot as plt
import pickle
ax = pickle.load(file('myplot.pickle'))
plt.show()
A small modification to Pelson’s answer for people working on a Jupyterhub
Use %matplotlib notebook
before loading the pickle. Using %matplotlib inline
did not work for me in either jupyterhub or jupyter notebook. and gives a traceback ending in
AttributeError: ‘module’ object has no attribute ‘new_figure_manager_given_figure’.
import matplotlib.pyplot as plt
import numpy as np
import pickle
%matplotlib notebook
ax = plt.subplot(111)
x = np.linspace(0, 10)
y = np.exp(x)
plt.plot(x, y)
with open('myplot.pkl','wb') as fid:
pickle.dump(ax, fid)
Then in a separate session:
import matplotlib.pyplot as plt
import pickle
%matplotlib notebook
with open('myplot.pkl','rb') as fid:
ax = pickle.load(fid)
plt.show()
Tested in jupyter notebook.
import matplotlib.pyplot as plt
import numpy as np
import pickle
fig, axes = plt.subplots(figsize=(20, 5),nrows=1, ncols=2)
x,y = np.arange(10), np.random.random(10)
axes[0].plot(x,y)
axes[1].plot(x,y)
plt.show()
# myfname = input("Save figure? [enter filename]: ")
myfname = 'test'
if (myfname!=''):
fig.savefig(f'./{myfname}.png')
print(f'file saved to ./{myfname}.png')
with open(f'./{myfname}.png.pkl','wb') as fid:
pickle.dump(fig, fid)
print(f'pickled to ./{myfname}.png.pkl')
###################################
####### in a separate session
myfname = 'test'
with open(f'./{myfname}.png.pkl', 'rb') as fh:
fig_loaded = pickle.load(fh)
print(fig_loaded.axes[0].lines[0].get_data()) # get data
fig_loaded # show fig