I am creating animated physics graphs with a transparent background for later use in a NLE. On my old machine at work they display and render with background transparency just fine. The exact same code however loses background transparency in the ffmpeg render on both my Linux and my Windows machine at home. The animations are displayed just fine on all machines.
As I first thought it was a Linux issue, I tried to run the code on my Windows machine expecting it to work again. Unfortunately it did not.
Reduced code:
import numpy as np
import matplotlib.pylab as plt
from matplotlib.animation import FuncAnimation
import matplotlib.animation as animation
from matplotlib.pyplot import figure
from matplotlib import style
import locale
from matplotlib.ticker import (MultipleLocator, AutoMinorLocator)
# Set to German locale to get comma decimal separater
locale.setlocale(locale.LC_NUMERIC, "de_DE")
# Tell matplotlib to use the locale we set above
plt.rcParams['axes.formatter.use_locale'] = True
# plt.clf()
# plt.rcdefaults()
# Style und Font definieren
style.use('dark_background')
# Pfeile erstellen
def arrowed_spines(fig, ax):
xmin, xmax = ax.get_xlim()
ymin, ymax = ax.get_ylim()
# removing the default axis on all sides:
for side in ['bottom','right','top','left']:
ax.spines[side].set_visible(False)
# removing the axis ticks
# plt.xticks([]) # labels
# plt.yticks([])
# ax.xaxis.set_ticks_position('none') # tick markers
# ax.yaxis.set_ticks_position('none')
# get width and height of axes object to compute
# matching arrowhead length and width
dps = fig.dpi_scale_trans.inverted()
bbox = ax.get_window_extent().transformed(dps)
width, height = bbox.width, bbox.height
# manual arrowhead width and length
hw = 1./20.*(ymax-ymin)
hl = 1./20.*(xmax-xmin)
lw = 1. # axis line width
ohg = 0.3 # arrow overhang
# compute matching arrowhead length and width
yhw = hw/(ymax-ymin)*(xmax-xmin)* height/width
yhl = hl/(xmax-xmin)*(ymax-ymin)* width/height
# draw x and y axis
ax.arrow(xmin, 0, xmax-xmin, 0., fc='w', ec='w', lw = lw,
head_width=hw, head_length=hl, overhang = ohg,
length_includes_head= True, clip_on = False)
ax.arrow(0, ymin, 0., ymax-ymin, fc='w', ec='w', lw = lw,
head_width=yhw, head_length=yhl, overhang = ohg,
length_includes_head= True, clip_on = False)
# Meine easing-Funktion
def ease(n):
if n < 0.0:
return 0
elif n > 1.0:
return 1
else:
return 3*n**2-2*n**3
# Meine Floor/Warte Funktion
def wait(n):
if n < 0.0:
return 0
else:
return n
# Canvas erstellen
fig = plt.figure()
ax = fig.add_subplot(111)
fig.set_size_inches([8,9])
def f(x):
return -0.05*x**2+125
xlin = np.linspace(0,60,100)
# Beschriftung und Optik
plt.xlabel(r"$x$ in $\rm{m}$", horizontalalignment='right', x=1.0)
plt.ylabel(r"$y$ in $\rm{m}$", horizontalalignment='right', y=1.0)
ax.set_xlim(0,100)
ax.set_ylim(0,139)
plt.grid(alpha=.4)
plt.xticks(np.arange(0, 100, 20))
plt.yticks(np.arange(0, 140, 20))
ax.yaxis.set_minor_locator(MultipleLocator(10))
ax.xaxis.set_minor_locator(MultipleLocator(10))
ax.tick_params(axis='x', direction = "inout", length= 10.0, which='both', width=3)
ax.tick_params(axis='y', direction = "inout", length= 10.0, which='both', width=3)
xsub = np.array([0])
# statische Linien definieren
line2, = ax.plot(xsub,f(xsub),linewidth=5,zorder=0,c = 'b')
arrowed_spines(fig, ax)
plt.tight_layout()
# Linien animieren
def animate(i):
xsub = xlin[0:wait(i-20)]
global line2
line2.remove()
line2, = ax.plot(xsub, f(xsub), linewidth=5, zorder=0,c = "b")
plt.tight_layout()
animation = FuncAnimation(fig, animate, np.arange(0, 130, 1), interval=100)
plt.show()
# animation.save(r"YOUR\PATH\HERE\reduced_x-y.mov", codec="png",
dpi=100, bitrate=-1,
savefig_kwargs={'transparent': True, 'facecolor': 'none'})