0

I already figured out how to save a video animation and zooming a picture with matplotlib. I want now to merge the two things and understand how to introduce zoom in an animation: reading some documentation I noticed it's not straightforward for just a picture, I expect to be the same or worse for a video.

In the following I write a simple working code, relating to that you can find on the first link

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

#Define x,y vectors and meshgrid with function u on it

x = np.arange(0,10,.1)
y = np.arange(0,10,.1)
X,Y = np.meshgrid(x,y)

#Create a figure and an axis object for the surface

fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')

#Animation without axes and with colormap

def animate(n):
    ax.cla()

    u = np.sin(X+Y+(n/10))
    plt.axis('off')
    plt.grid('off')
    ax.plot_surface(X,Y,u,cmap=cm.inferno)

    return fig,     

anim = animation.FuncAnimation(fig,animate,frames=63)
anim.save('A.mp4',fps=20)

Here the output

enter image description here

As you can see is not bad zoomed, but it's not enough, I want it more!

In the actual code I'm using, video animations are very very small, and I don't know why because it's very similar to this. I hope also that this way I can increase video quality, that is quite poor. Thanks for any help.

Rob Tan
  • 159
  • 9
  • Image size is figure size in inches times dpi (dots per inch). If you want more resolution increase either one or both. – Jody Klymak Jan 24 '22 at 19:47
  • But my problem is, fundamentally, all the unuseful white space around the image. I'm not sure that matplotlib consider it something different from the image itself – Rob Tan Jan 24 '22 at 20:14
  • You could probably edit the original to clarify. Did you try passing bbox_inches='tight' to `anim.save`? – Jody Klymak Jan 24 '22 at 20:37
  • 1
    Yes, but it didn't work – Rob Tan Jan 25 '22 at 10:42
  • True, that `bbox_inches` is ignored (and even produces a message telling you this) in anim.save although the docs say it can be passed as a dictionary. Unless you find a better way, I would generate as a workaround individually cropped images and animate them with [ArtistAnimation](https://matplotlib.org/stable/api/_as_gen/matplotlib.animation.ArtistAnimation.html), matplotlib's flip book equivalent. – Mr. T Jan 25 '22 at 11:08
  • @Mr.T How would you do this? You mean with the same method you explained for the picture case (second link)? – Rob Tan Jan 25 '22 at 13:20
  • 1
    Yes, crop each image, then animate the image collection via [ArtistAnimation](https://stackoverflow.com/a/65622369/8881141). Still, I cannot believe there is no better method. – Mr. T Jan 25 '22 at 13:26
  • @Mr.T Thank you, I'll take a look – Rob Tan Jan 25 '22 at 13:53

1 Answers1

0

I finally got to a raw, but effective solution. The code almost doesn't change

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

#Define x,y vectors and meshgrid with function u on it

x = np.arange(0,10,.1)
y = np.arange(0,10,.1)
X,Y = np.meshgrid(x,y)

#Create a figure and an axis object for the surface

fig = plt.figure(frameon=False)
ax = fig.add_subplot(111,projection='3d')

#Definition? and zooming

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

#Animation without axes and with colormap

def animate(n):
    ax.cla()

    u = np.sin(X+Y+(n/10))
    plt.axis('off')
    plt.grid('off')
    ax.plot_surface(X,Y,u,cmap=cm.inferno)
    print(n)

    return fig,     

anim = animation.FuncAnimation(fig,animate,frames=63)
anim.save('A.gif',fps=20)

enter image description here

As you can see the zooming is good. The bad quality is due to compression I did in a second moment, because the actual output gif is quite heavy with those parameters, in fact the quality is very good.

Rob Tan
  • 159
  • 9