.ipynb

An .ipynb file is a Jupyter notebook: a JSON document containing an ordered list of cells, each with its source and, for code cells, the outputs captured the last time it ran.

{
  "cells": [
    { "cell_type": "markdown", "source": ["# Retention analysis\n"] },
    {
      "cell_type": "code",
      "execution_count": 7,
      "source": ["df.groupby('cohort').retention.mean().plot()\n"],
      "outputs": [
        {
          "output_type": "display_data",
          "data": { "image/png": "iVBORw0KGgo…", "text/plain": ["<Axes: >"] }
        }
      ]
    }
  ],
  "metadata": { "kernelspec": { "name": "python3" } },
  "nbformat": 4,
  "nbformat_minor": 5
}

Outputs live in the file, and that is the whole problem

Storing outputs is what makes a notebook self-describing — you can read someone's analysis without running it. It is also why:

  • Diffs are unreadable. A re-run changes execution counts and re-encodes every image, so a one-character edit shows as thousands of changed lines. nbstripout or jupytext in a pre-commit hook is the standard defence.
  • Files get big fast. Base64 images inflate by a third. Multi-megabyte notebooks are ordinary, and GitHub's inline renderer gives up on them.
  • Merge conflicts corrupt them. A conflicted JSON document is not a notebook, and the error a reader sees is a parse failure, not a merge marker.

What survives an HTML export

jupyter nbconvert --to html notebook.ipynb produces a page with no kernel behind it.

Survives Does not survive
Markdown, code, text and table output ipywidgets sliders and inputs
matplotlib and seaborn images @interact callbacks
Plotly, Bokeh, Altair (they embed their own JS) Anything recomputing on view
Stack traces and stderr input() prompts

The widget case is the frequent surprise: the export contains the widget state but not the Python that responds to it, so the control renders and does nothing — or renders as a blank area (why widgets don't render).

Interactive charts are the opposite story. Plotly and Bokeh ship their interactivity as JavaScript inside the output, so zoom, hover and legend toggles work in a published HTML export exactly as they did in the notebook — provided the report is served somewhere that lets scripts run (interactive HTML reports).

Sending the analysis, not the file

Sending the .ipynb requires the recipient to have Python, the environment, and a reason to trust the file. Exporting to HTML and publishing it gives them a URL that opens on a phone, keeps the charts live, and can be commented on — so a stakeholder selects the number they are querying and asks about it there, rather than screenshotting it into a thread (comment on HTML).

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Publish a notebook →

Related