HTML and file export#

Open in Colab

View or download this notebook on GitHub.

Most sharing should use interactive HTML: one browser file that opens without a Python kernel and keeps the widget controls live. When collaborators need to keep working in Python, share the saved notebook with its widget state instead.

Need

Best format

Why

Receiver opens

Share a finished interactive view

Interactive HTML

One portable browser file, no Python kernel

.html in a browser

Continue the analysis together

Saved notebook with widget state

Keeps code, outputs, and widget state together

.ipynb in JupyterLab or VS Code

Put an image in a paper or slide

PNG figure

Static, compact, easy to cite

.png

Put a time series in slides or email

GIF animation

Plays without widget JavaScript

.gif

Reopen the same widget settings later

JSON view state

Small settings file for Python workflows

.json

Send a complete report package

ZIP bundle

Groups HTML, figures, and state files

.zip

This page uses the same real gold HAADF moving-crop stack as the Show3D tutorial, so the export examples match the data users see elsewhere in the docs. It follows the common order: HTML first, notebook sharing second, then smaller supporting exports.

import quantem.widget as qw
qw.profile()

import os, pathlib, tempfile

os.environ.setdefault("HF_HUB_DISABLE_PROGRESS_BARS", "1")

from quantem.widget import Show2D, Show3D
from quantem.widget.datasets import show3d_gold

out = pathlib.Path(tempfile.mkdtemp(prefix="quantem_widget_share_"))

# Real gold HAADF moving-crop stack used by the Show3D tutorial.
volume_dataset = show3d_gold(size="small", verbose=False)
first_frame = volume_dataset.array[0]
image_sampling = volume_dataset.sampling[1:]
image_units = volume_dataset.units[1:]
volume_dataset.array.shape, first_frame.shape
quantem.widget  0.0.1rc44.dev0
  install       editable checkout
  commit        2d009a7f61ee (dirty checkout)
quantem.gpu     0.0.1rc18.dev0
  install       local build
  commit        not recorded
quantem         0.1.10
  install       installed package
  commit        not recorded
webgpu kernels  fa4a86c (fa4a86cfee85), pinned fa4a86cfee85ea719be2dd98206d2098f0dd3344
torch           2.14.1+cu130  device=cpu
python          3.12.15
show3d_gold(size='small') crops from every 8th pixel of the 4096x4096 image; size='full' crops native pixels.
((32, 256, 256), (256, 256))

1. Export interactive HTML#

Use HTML when someone should open the result in a browser and still scrub, zoom, change contrast, or use the widget controls. This is usually the best default for sharing a finished interactive view.

Show3D and Show3DSlices can write a single self-contained HTML file that keeps the scrub interactive with no kernel. Two common encodings are:

  • exact (default): embeds float32 bytes and preserves numerical precision.

  • encoded uint8: embeds a compact display pack plus global min/max - much smaller, and visually identical after the colormap for most sharing.

In the widget below, click Export to download the current interactive HTML file to your local device. Use that downloaded .html file when you want to share the interactive gold HAADF stack directly.

show3d = Show3D(volume_dataset, panel_width_px=520)
exact = show3d.export_html(out / 'gold_haadf_exact.html')
quant = show3d.export_html(out / 'gold_haadf_uint8.html', encoding="uint8")
for p in (exact, quant):
    print(f'{p.name:24s} {p.stat().st_size/1e6:6.2f} MB')

# The same widget state is what the exported HTML opens in a browser.
show3d
gold_haadf_exact.html     13.33 MB
gold_haadf_uint8.html      4.94 MB

2. Export an animation for slides or email#

Use GIF when someone should see the movie in PowerPoint, Keynote, email, or a static report. This is different from HTML: the animation plays anywhere, but the receiver cannot keep zooming, panning, or changing contrast.

The widget Export menu first asks for the format: GIF or Interactive HTML. The GIF panel exposes frame range, maximum frame count, fps, spatial size, and estimated render size before compression. The Slides preset sets a slide-friendly starting point: at most 40 frames with a 512 px panel edge.

For notebooks or scripted reports, use Python when you need the same presentation-specific options from code:

show3d.save_gif("gold_movie_slides.gif", quality="medium", fps=8, slides_preset=True)
show3d.save_gif("gold_movie.gif", quality="medium", fps=6, frame_start=0, frame_stop=24, max_frames=12, max_edge_px=768)

3. Share the notebook with widget state#

Use the notebook when collaborators should rerun cells, edit analysis code, or continue the work in JupyterLab or VS Code. Interact with the widgets, save the notebook, and share the .ipynb with any needed data files.

Open analysis.ipynb in JupyterLab or VS Code, interact with the widgets, then save the notebook.

A saved widget notebook contains two pieces: a widget output in the cell and metadata.widgets at the notebook level. Opening that notebook in a compatible Jupyter frontend reuses the saved state, so the receiver sees the same widget view before rerunning anything.

Warning

Jupyter trust matters. In end-to-end tests with Show2D and Show3D, untrusted copied notebooks kept the saved widget metadata but showed a plain text widget summary instead of the interactive canvas. Trust a notebook only when you know the source, or rerun the cells yourself. After trust, the saved widget state restores in JupyterLab.

GitHub’s native notebook preview is different: it does not run widget JavaScript. Use the documentation site, Colab, Jupyter, or jupyter nbconvert --to html when you want interaction. Only make a GitHub-preview copy when you deliberately want static pictures in GitHub’s .ipynb renderer.

cp analysis.ipynb analysis_github.ipynb
quantem github analysis_github.ipynb --no-execute

4. Save a reusable widget view#

save() writes a small, versioned JSON file capturing the current view: colormap, contrast, ROIs, zoom, and related widget settings. Use this when you want to restore the same view inside Python later, not as the primary sharing format.

show2d = Show2D(
    first_frame,
    cmap="magma",
    sampling=image_sampling,
    units=image_units,
    title="Gold HAADF frame",
)
state_path = out / "gold_haadf_view.json"
show2d.save(state_path)
print("state:", state_path.name, "-", state_path.stat().st_size, "bytes")
state: gold_haadf_view.json - 3117 bytes

5. Save a figure#

save_image() writes the colormapped image directly, or a publication-style figure with a title, colorbar, and scale bar when you ask for them. Use this for static figures, not interactive sharing.

png_path = show2d.save_image(out / 'gold_haadf_frame.png', show_scale_bar=True, colorbar=True, title='Gold HAADF frame')
print('figure:', png_path.name, '-', png_path.stat().st_size, 'bytes')
figure: gold_haadf_frame.png - 629283 bytes

6. Export Show2D SVG for Illustrator#

Use the Show2D Export menu and choose SVG. The export keeps panel frames, marker bars, panel labels, scale bars, geometric overlays, local annotations, inset plots, group markers, and colorbars as editable SVG objects. The scientific image panels stay as embedded PNG images inside the SVG, because measured pixel data is not vectorized. SVG export uses a high-resolution embedded image scale by default; from Python, pass a smaller scale only when file size matters.

From Python, call export_svg() on the current widget state.

svg_path = show2d.export_svg(out / 'gold_haadf_figure.svg', include_scale_bar=True)
print('svg:', svg_path.name, '-', svg_path.stat().st_size, 'bytes')
svg: gold_haadf_figure.svg - 293890 bytes

7. Bundle shared files#

Exported HTML, PNG, and JSON state files are ordinary files. If a collaborator needs several of them together, bundle them with the standard library.

import zipfile
bundle = out / 'widget_report.zip'
with zipfile.ZipFile(bundle, 'w', zipfile.ZIP_DEFLATED) as zf:
    for p in [state_path, png_path, exact, quant]:
        zf.write(p, arcname=p.name)
print('bundle:', bundle.name, '-', bundle.stat().st_size/1e6, 'MB')
print('contains:', zipfile.ZipFile(bundle).namelist())
bundle: widget_report.zip - 9.990172 MB
contains: ['gold_haadf_view.json', 'gold_haadf_frame.png', 'gold_haadf_exact.html', 'gold_haadf_uint8.html']

Tip

For embedding a widget in these docs (or any nbconvert/Jupyter Book page), construct it with save_state=True and let the notebook bake the state: the same mechanism export_html uses, but inline in the page.