Reputation: 75
Hello I just finished to write a code that compute the orbitals of the hydrogen atom. I wrote a for loop to create 300 pictures using the command
plt.savefig("image{i}.png".format(i=i))
Now I wanted to ask what is the easiest way to create a high quality .mp4 or .gif file out of the pictures using python. I saw several tutorials that didn't helped me because the gif was messed up or the quality was too low.
Thank you for your support
Upvotes: 4
Views: 6466
Reputation: 10320
The faster way is to use imageio
as in @ShlomiF's answer, but you can do the same thing with pure matplotlib if you so prefer:
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
nframes = 25
plt.subplots_adjust(top=1, bottom=0, left=0, right=1)
def animate(i):
im = plt.imread('image'+str(i)+'.png')
plt.imshow(im)
anim = FuncAnimation(plt.gcf(), animate, frames=nframes,
interval=(2000.0/nframes))
anim.save('output.gif', writer='imagemagick')
But if your first priority is the quality of the output you may want to consider using ffmpeg
and convert
directly,
ffmpeg -f image2 -i image%d.png output.mp4
ffmpeg -i output.mp4 -vf "fps=10,scale=320:-1:flags=lanczos" -c:v pam -f \
image2pipe - | convert -delay 10 - -loop 0 -layers optimize output.gif
Changing the scale
argument as needed to control the size of the final output, scale=-1:-1
leaves the size unchanged.
Upvotes: 2
Reputation: 480
I too found gif's to be too poor quality, so sought a solution to make an mp4 with higher resolution and playback control. I haven't found an mp4 solution, but I have been able to write .avi movie files using the Python cv2
library. Here's an example:
import cv2
# Create avi movie from static plots created of each time slice
image_folder = 'path_to_png_files'
video_name = '/mov-{}.avi'.format('optional label')
# Store individual frames into list
images = [img for img in os.listdir(image_folder) if img.endswith(".png")]
# Create frame dimension and store its shape dimensions
frame = cv2.imread(os.path.join(image_folder, images[0]))
height, width, layers = frame.shape
# cv2's VideoWriter object will create a frame
video = cv2.VideoWriter(avi_path + video_name, 0, 1, (width,height))
# Create the video from individual images using for loop
for image in images:
video.write(cv2.imread(os.path.join(image_folder, image)))
# Close all the frames
cv2.destroyAllWindows()
# Release the video write object
video.release()
Upvotes: 0
Reputation: 2895
The easiest I know is to use imageio
's mimwrite
.
import imageio
ims = [imageio.imread(f) for f in list_of_im_paths]
imageio.mimwrite(path_to_save_gif, ims)
There are obvious options such as duration, number of loops, etc.
And some other options you can read about in the documentation by using imageio.help('gif')
.
Hope that helps.
Upvotes: 2