Mplot3d animation with transparent background

I want to generate some gifs with a transparent background using matplotlib. I tried different options, but I can not get the files with a transparent background. With the current setting, I get the first frame, but not all the others. Below is my code

from __future__ import division from numpy import pi, sin, cos, mgrid from scipy.special import jn, jn_zeros from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt import matplotlib.animation as animation from matplotlib import rcParams # In Windows the next line should provide the full path to convert.exe # since convert is a Windows command rcParams['animation.convert_path'] = "C:\Program Files\ImageMagick-6.9.3\convert.exe" rcParams['savefig.transparent'] = True rcParams['savefig.dpi'] = 130 rcParams['savefig.pad_inches'] = 0 plot_args = {'rstride': 1, 'cstride': 1, 'cmap':"RdYlBu", 'linewidth': 0.5, 'antialiased': True, 'color': '#1e1e1e', 'shade': True, 'alpha': 1.0, 'vmin': -1, 'vmax':1} def data_gen(num): ax.cla() m, n = 1, 2 lam = jn_zeros(m, n)[-1] dt = 2*pi/(30*lam) z = cos(m*t)*jn(m, lam*r)*sin(lam*num*dt) surf = ax.plot_surface(x, y, z, **plot_args) ax.view_init(elev=30, azim=45) ax.set_xlim(-0.6, 0.6) ax.set_ylim(-0.6, 0.6) ax.set_zlim(-1, 1) plt.axis("off") return surf r, t = mgrid[0:1:20j, 0:2*pi:40j] x, y = r*cos(t), r*sin(t) fig = plt.figure(facecolor=None) ax = fig.add_subplot(111, projection='3d') ani = animation.FuncAnimation(fig, data_gen, range(30), blit=False) ani.save("Drum vibration mode.gif", writer='imagemagick') 

This gives the result (if you click on it, you will see that only one frame is transparent)

Question: Is there a way to get animation with a transparent background using mplot3d?

enter image description here

+8
python matplotlib animated-gif mplot3d
source share
1 answer

I think this is really a mistake. However, if you care more about the result than about how to get there, the following will do the job. Instead of invoking an animation, you can save each image separately, and then call imageMagick to convert them to an animated gif. See the code below and consider the arguments to convert.exe.

 from __future__ import division from numpy import pi, sin, cos, mgrid from scipy.special import jn, jn_zeros from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt from matplotlib import rcParams import subprocess # In Windows the next line should provide the full path to convert.exe # since convert is a Windows command path_to_convert = "C:\Program Files\ImageMagick-6.9.3\convert.exe" #rcParams['animation.convert_path'] = path_to_convert rcParams['savefig.transparent'] = True rcParams['savefig.dpi'] = 130 rcParams['savefig.pad_inches'] = 0 plot_args = {'rstride': 1, 'cstride': 1, 'cmap':"RdYlBu", 'linewidth': 0.5, 'antialiased': True, 'color': '#1e1e1e', 'shade': True, 'alpha': 1.0, 'vmin': -1, 'vmax':1} def data_gen(num): ax.cla() ax.clear() m, n = 1, 2 lam = jn_zeros(m, n)[-1] dt = 2*pi/(30*lam) z = cos(m*t)*jn(m, lam*r)*sin(lam*num*dt) surf = ax.plot_surface(x, y, z, **plot_args) ax.view_init(elev=30, azim=45) ax.set_xlim(-0.6, 0.6) ax.set_ylim(-0.6, 0.6) ax.set_zlim(-1, 1) ax.axis("off") fig.patch.set_visible(False) ax.patch.set_visible(False) ax.set_axis_off() ax._axis3don = False return surf r, t = mgrid[0:1:20j, 0:2*pi:40j] x, y = r*cos(t), r*sin(t) fig = plt.figure(facecolor=None, frameon=False) ax = fig.add_subplot(111, projection='3d') for i in range(30): data_gen(i) plt.savefig("drum_{n:02d}.png".format(n=i), transparent=True, frameon=False) print i, args = [path_to_convert, "-delay", "10", "-loop" , "0", "-dispose", "Background", "drum_*.png", "output.gif"] subprocess.call(args, shell=True) subprocess.call(["del", "/Q", "drum_*.png"], shell=True) print "\ndone" 

Remember that imageMagick calls and the delete command may be system dependent. This script has been tested with imageMagick 7.0.3 (Q16) under Windows 8.

+4
source share

All Articles