3

On Windows, when I save 3D matplotlib surface plots using the pickle module and reload them, the plots lack any interactive functionality, such as being able to rotate the plots or zoom in on the plots. However, if I save and reload 2D pickled matplotlib plots, I am still able to interact with the plots, at least with the zoom tools. The following code recreates the successful 2D plot case.

import matplotlib.pyplot as plt
import numpy as np
import pickle


xs = np.linspace(0, 4*np.pi, 100)
ys = np.sin(xs)

fig, ax = plt.subplots()
ax.plot(xs, ys)

with open("plot.pickle", 'wb') as file:
    pickle.dump(fig, file)

plt.show()

plt.close(fig)

with open("plot.pickle", 'rb') as file:
    fig = pickle.load(file)

plt.show()

The following code is a small example that recreates the 3D plot problem.

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import pickle


xs = np.linspace(0, 1, 100)
ys = np.linspace(0, 4*np.pi, 100)
zs = np.zeros((100, 100))

for i, amp in enumerate(xs):
    for j, phase in enumerate(ys):
        zs[j, i] = amp*np.sin(phase)

xs, ys = np.meshgrid(xs, ys)
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
ax.plot_surface(xs, ys, zs)

with open("plot.pickle", 'wb') as file:
    pickle.dump(fig, file)

plt.close(fig)

with open("plot.pickle", 'rb') as file:
    fig = pickle.load(file)

plt.show()

What changes can I make so that my 3D pickled plots will have interactive rotate and zoom functionality? If such functionality is not possible with 3D pickled plots, are they any alternative methods for saving (without having to originally show the plot in a window) and reloading interactive 3D matplotlib surface plots?

scruffaluff
  • 345
  • 4
  • 20

1 Answers1

0

I found not a solution but a work-around. The work-around is to save all data needed to draw r=the figure plus the function that draws it in a pickle-file.

To do this, I needed to use dill instead of picke, as advised bu @JoshRosen in his answer to Is there an easy way to pickle a python function (or otherwise serialize its code)?

Create the pickle:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import dill as pickle


def plotfun(plotdata):
    ax = plt.gca()
    ax.plot_surface(plotdata['xs'], plotdata['ys'], plotdata['zs'])


xs = np.linspace(0, 1, 100)
ys = np.linspace(0, 4*np.pi, 100)
zs = np.zeros((100, 100))
for j, phase in enumerate(ys):
    zs[j, :] = xs*np.sin(phase)
xs, ys = np.meshgrid(xs, ys)

fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
plotdata = {'xs': xs, 'ys': ys, 'zs': zs, 'plotfun': plotfun}
plotdata['plotfun'](plotdata)
with open("test.pickle", 'wb') as file:
    pickle.dump(plotdata, file)

Load the pickle

import dill as pickle
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt


plt.figure().add_subplot(111, projection='3d'),
plotdata = pickle.load(open('test.pickle', 'rb'))
plotdata['plotfun'](plotdata)
plt.show()
Nathan
  • 3,558
  • 1
  • 18
  • 38