Created
October 16, 2018 14:19
-
-
Save ClementC/8cf6edf9eeccf1ab692db8f7dd8f2062 to your computer and use it in GitHub Desktop.
Small script and descriptions of steps to extract a GIF for a matplotlib animation widget embedded in a Jupyter notebook.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Matplotlib animations can be saved as a widget in a Jupyter notebook. | |
# It's unclear to how to recover it in Python once the notebook kernel has been restarted. | |
# But the image data is there in the notebook, embedded in a JS script in the output of the cell | |
# with the individual frames encoded as base64 png images. | |
# So here's the way I found to extract the images and make a GIF out of them. | |
# It's not all automatic and needs some manual action. | |
# Steps: | |
# 1/ Open the notebook in a web browser. Open the developer tools, and in the console, start typing "anim" | |
# then TAB to autocomplete. A variable with a unique name looking like "animae693007f74d44b0b917c61003e9490f" should appear. | |
# Cut this variable name, and copy it in the following command that you can then execute: | |
# JSON.stringify(animae693007f74d44b0b917c61003e9490f.frames.map(function(elem) {return elem.src;})) | |
# Copy the output that appears. | |
# 2/ Open your favorite text editor, preferably not terminal-based; the output can be several Mo of text, | |
# and terminal usually don't react well to this. I used Sublime Text for this step. | |
# Paste the output, and save it under "frames.json" | |
# 3/ Create a "frames" directory next to it | |
# 3/ Fire an IPython terminal, pip install imageio if you don't have it, and execute the code below. | |
# 4/ You can now admire the created GIF and marvel at the wonders of technology. | |
import base64 | |
import json | |
import imageio | |
with open("frames.json") as f: | |
frames = json.load(f) | |
print("Found %d frames." % len(frames)) | |
# Exporting individual frames as PNG images | |
for idx, frame in enumerate(frames): | |
with open("%d.png" % (idx + 1), "wb") as f: | |
f.write(base64.b64decode(frame.split("base64,")[1])) | |
# Opening all frames and creating a GIF | |
# With the options there it will loop, and each frame will be displayed for 200ms | |
with imageio.get_writer('./my_gif.gif', mode='I', duration=0.2) as writer: | |
filenames = ["./frames/%d.png" % i for i in range(1, 31)] | |
# If you want to have the GIF looping back-and-forth, you can replace the for-loop below by the commented one | |
# for filename in filenames + filenames[:-1:-1]: | |
for filename in filenames: | |
image = imageio.imread(filename) | |
writer.append_data(image) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment