Matplotlib.animation: how to remove a white edge

I am trying to generate a movie using the matplotlib machine. If I do this, I always get a white marker around the video. Does anyone know how to remove this margin?

Corrected example from http://matplotlib.org/examples/animation/moviewriter.html

# This example uses a MovieWriter directly to grab individual frames and # write them to a file. This avoids any event loop integration, but has # the advantage of working with even the Agg backend. This is not recommended # for use in an interactive setting. # -*- noplot -*- import numpy as np import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt import matplotlib.animation as manimation FFMpegWriter = manimation.writers['ffmpeg'] metadata = dict(title='Movie Test', artist='Matplotlib', comment='Movie support!') writer = FFMpegWriter(fps=15, metadata=metadata, extra_args=['-vcodec', 'libx264']) fig = plt.figure() ax = plt.subplot(111) plt.axis('off') fig.subplots_adjust(left=None, bottom=None, right=None, wspace=None, hspace=None) ax.set_frame_on(False) ax.set_xticks([]) ax.set_yticks([]) plt.axis('off') with writer.saving(fig, "writer_test.mp4", 100): for i in range(100): mat = np.random.random((100,100)) ax.imshow(mat,interpolation='nearest') writer.grab_frame() 
+4
source share
3 answers

Passing None as an argument to subplots_adjust does not do what you think the (doc) is doing. This means "use default value." To do what you want, use the following instead:

 fig.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=None, hspace=None) 

You can also make your code much more efficient if you reuse your ImageAxes object ImageAxes

 mat = np.random.random((100,100)) im = ax.imshow(mat,interpolation='nearest') with writer.saving(fig, "writer_test.mp4", 100): for i in range(100): mat = np.random.random((100,100)) im.set_data(mat) writer.grab_frame() 

By default, imshow fixes the proportions equal, i.e. your pixels are square. You need to resize the shape in the same way as your images:

 fig.set_size_inches(w, h, forward=True) 

or say imshow to use an arbitrary aspect ratio

 im = ax.imshow(..., aspect='auto') 
+7
source

In a recent matplotlib build , it looks like you can pass arguments to the author:

 def grab_frame(self, **savefig_kwargs): ''' Grab the image information from the figure and save as a movie frame. All keyword arguments in savefig_kwargs are passed on to the 'savefig' command that saves the figure. ''' verbose.report('MovieWriter.grab_frame: Grabbing frame.', level='debug') try: # Tell the figure to save its data to the sink, using the # frame format and dpi. self.fig.savefig(self._frame_sink(), format=self.frame_format, dpi=self.dpi, **savefig_kwargs) except RuntimeError: out, err = self._proc.communicate() verbose.report('MovieWriter -- Error running proc:\n%s\n%s' % (out, err), level='helpful') raise 

If so, you can pass bbox_inches="tight" and pad_inches=0 to grab_frame -> savefig, and this should remove most of the border. However, the latest version on Ubuntu still has this code:

 def grab_frame(self): ''' Grab the image information from the figure and save as a movie frame. ''' verbose.report('MovieWriter.grab_frame: Grabbing frame.', level='debug') try: # Tell the figure to save its data to the sink, using the # frame format and dpi. self.fig.savefig(self._frame_sink(), format=self.frame_format, dpi=self.dpi) except RuntimeError: out, err = self._proc.communicate() verbose.report('MovieWriter -- Error running proc:\n%s\n%s' % (out, err), level='helpful') raise 

So it looks like functionality has been added to it. Take this version and take a picture!

+1
source

If you just want to keep the matshow / imshow matrix rendering without axis annotation, then the latest version of scikit-video (skvideo) may also be relevant if you have avconv installed. An example in the distribution shows a dynamic image built from the numpy function: https://github.com/aizvorski/scikit-video/blob/master/skvideo/examples/test_writer.py

Here is my example modification:

 # Based on https://github.com/aizvorski/scikit-video/blob/master/skvideo/examples/test_writer.py from __future__ import print_function from skvideo.io import VideoWriter import numpy as np w, h = 640, 480 checkerboard = np.tile(np.kron(np.array([[0, 1], [1, 0]]), np.ones((30, 30))), (30, 30)) checkerboard = checkerboard[:h, :w] filename = 'checkerboard.mp4' wr = VideoWriter(filename, frameSize=(w, h), fps=8) wr.open() for frame_num in range(300): checkerboard = 1 - checkerboard image = np.tile(checkerboard[:, :, np.newaxis] * 255, (1, 1, 3)) wr.write(image) print("frame %d" % (frame_num)) wr.release() print("done") 
0
source

All Articles