Export images from Jupyter Notebook using command line
By: Damien Marlier
Tags: Exploratory Data Analysis, Python, Jupyter Notebook

Introduction

I am doing a lot of EDAs on Jupyter Notebook, and very often lots of images are generated through the process with libraries such as matplotlib or seaborn. I occasionally need to export them to include them within presentations or documentation.

Methods I used to deal with this exportation were very manual:

Option 1: Saving figures programmatically (e.g. fig.savefig for matplotlib)

Option 2: Right click on image and “Save Image As”

Option 3: Screenshot!

These methods above work well when I am dealing with few images. However, for a larger number of images and if done on a daily basis, this process can become VERY tedious…

Doing some research to find more automated solutions, nothing came up…

As I didn’t want to keep wasting precious time on “Save Image As” actions, I decided to come up with a quick workaround myself.

Below is a quick walk-through the process. I hope you will find it useful!

Step 1: Looking into Jupyter Notebook file structure

First, it is important to better understand what a .ipynb file looks like from the inside. Let’s consider a notebook with the following content:

# [cell 1]

import matplotlib.pyplot as plt



import numpy as np # [cell 2]

x = np.linspace(0, 10, 100)

y0 = np.sin(x)

y1 = np.cos(x) # [cell 3]

plt.plot(x, y0)

plt.show()

plt.plot(x, y1)

plt.show()

The code is pretty straightforward.

It gets a list of 100 numbers between 0 and 10. Sinus and Cosinus values are computed for each of these number. The points are then plotted and displayed using matplotlib visualisation library.

This is what it looks like from outside

If you open this notebook with your text editor, you get to see what it looks like from inside:

{

"cells": [

{

"cell_type": "code",

"execution_count": 1,

"metadata": {

"collapsed": true

},

"outputs": [],

"source": [

"import matplotlib.pyplot as plt

",

"import numpy as np"

]

},

{

"cell_type": "code",

"execution_count": 2,

"metadata": {

"collapsed": true

},

"outputs": [],

"source": [

"x = np.linspace(0, 10, 100)

",

"y0 = np.sin(x)

",

"y1 = np.cos(x)"

]

},

{

"cell_type": "code",

"execution_count": 3,

"metadata": {},

"outputs": [

{

"data": {

"image/png": "iVBORw0...",

"text/plain": [

"<Figure size 432x288 with 1 Axes>"

]

}, {

"data": {

"image/png": "iVBORw0...",

"text/plain": [

"<Figure size 432x288 with 1 Axes>"

]

},

"metadata": {},

"output_type": "display_data"

}

],

"source": [

"plt.plot(x, y0)

",

"plt.show()

",

"plt.plot(x, y1)

",

"plt.show()"

]

},

........

}

hhhmm, It could have been scarier! We can see that the file is structured as a JSON. Additionally, we can note that plotted images are base64-encoded and are directly embedded into the JSON with associated key being “image/png”.

Therefore, it seems that a quick solution to our problem would be to somehow parse the notebook file and get the encoded images. Ok! Let’s go!

Step 2: Parsing with python

To solve our problem, we are going to create a python class called NotebookImageExporter. Its scope is fairly simple:

Convert notebook file into a nested python dictionary

Locate where the encoded images are within the dictionary

Extract encoded images from dictionary

Save encoded images as image files in desired folder

Skipping all the details, here is what the final file (exporter.py) looks like:

Step 3: Packaging time!

Great! We now have some python code ready.

However, as much as possible, I don’t want to add extra code in my notebook. Actually, it would be great if I could export my images directly from command line. It would be even better if from a single command line. Something like below:

my_command my_notebook_filepath -o my_output_directory

Let’s work on that!