Jupyter Notebook
Image Embedding
Local Images
Web Resource
Data Visualization

How to embed image or picture in jupyter notebook, either from a local machine or from a web resource?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Jupyter notebooks can display images in several ways, and the best method depends on whether the image is local, remote, static, or generated by code. Markdown is convenient for simple narrative notebooks, while the Python display APIs are better when paths, sizes, or sources need to be controlled programmatically.

Use Markdown for Simple Static Images

If the image path is stable and you just want it to appear in the notebook output, Markdown is the simplest option.

For a local file:

markdown
![Training Plot](images/training-plot.png)

For a remote image:

markdown
![Example Image](https://httpbin.org/image/png)

This is ideal for reports, tutorials, and notebooks that mix explanation with a few fixed figures. The main advantage is readability: anyone opening the notebook can immediately see what the image is supposed to represent.

The main limitation is that Markdown does not give you much runtime control. You cannot easily check that the file exists first, compute the path dynamically, or adjust behavior based on notebook state.

Use IPython.display.Image for Programmatic Control

When the image path comes from code, or when you want to control width and height from variables, use IPython.display.

python
1from pathlib import Path
2from IPython.display import Image, display
3
4image_path = Path("images") / "training-plot.png"
5
6if image_path.exists():
7    display(Image(filename=str(image_path), width=500))
8else:
9    print(f"Missing image: {image_path}")

You can also display an image directly from a URL:

python
from IPython.display import Image, display

display(Image(url="https://httpbin.org/image/jpeg", width=320))

This method is better when the notebook is part of a workflow rather than just a static document. It also makes it easy to reuse the same logic inside loops or helper functions.

Render Image Data with Matplotlib

If the image itself is part of your analysis, load it as data and render it with a plotting library. This is useful when you want to compare images, annotate them, or apply image-processing steps before display.

python
1from pathlib import Path
2from PIL import Image
3import matplotlib.pyplot as plt
4
5image_path = Path("images") / "training-plot.png"
6img = Image.open(image_path)
7
8fig, ax = plt.subplots(figsize=(6, 4))
9ax.imshow(img)
10ax.set_title("Training Plot")
11ax.axis("off")
12plt.show()

This approach gives you much more control over layout, titles, subplots, and side-by-side comparison. It is often the best fit when the image is part of the actual computation, not just supporting documentation.

Download Remote Images Before Displaying

Direct remote links are convenient, but they reduce reproducibility. If the image is important to the notebook, download it first so the notebook can still run offline and does not depend on the external server remaining available.

python
1from pathlib import Path
2import requests
3from IPython.display import Image, display
4
5
6def fetch_image(url: str, output_path: Path) -> Path:
7    output_path.parent.mkdir(parents=True, exist_ok=True)
8
9    with requests.get(url, stream=True, timeout=20) as response:
10        response.raise_for_status()
11
12        content_type = response.headers.get("Content-Type", "")
13        if not content_type.startswith("image/"):
14            raise ValueError(f"Expected image response, got {content_type!r}")
15
16        with open(output_path, "wb") as file_handle:
17            for chunk in response.iter_content(8192):
18                if chunk:
19                    file_handle.write(chunk)
20
21    return output_path
22
23
24saved_path = fetch_image("https://httpbin.org/image/png", Path("images") / "remote.png")
25display(Image(filename=str(saved_path), width=320))

This pattern is more work, but it makes the notebook more stable for teams and future reruns.

Keep Notebook Paths Portable

Hard-coded absolute paths are one of the fastest ways to break a notebook when it moves to another machine. Prefer relative paths and pathlib.

python
1from pathlib import Path
2
3notebook_dir = Path.cwd()
4image_dir = notebook_dir / "images"
5print(image_dir)

A practical convention is to keep images in a folder near the notebook or at a repository-level images/ directory. That makes the notebook easier to share and version-control.

Self-Contained Notebooks with Base64

If you need the notebook to show an image even when the external file is missing, you can embed the data directly into HTML as a base64 string.

python
1from pathlib import Path
2import base64
3from IPython.display import HTML
4
5image_path = Path("images") / "training-plot.png"
6encoded = base64.b64encode(image_path.read_bytes()).decode("ascii")
7HTML(f'<img src="data:image/png;base64,{encoded}" width="450">')

This makes the notebook more self-contained, but it also increases notebook size and can make diffs noisy in version control. It is best reserved for a small number of critical images.

Common Pitfalls

The most common mistake is using absolute local paths, which makes the notebook fail on another machine immediately. Another is relying on remote images for important outputs, only to discover later that the URL changed or the server is unavailable. Developers also mix several display styles in one notebook without a clear reason, which makes maintenance harder. Finally, very large images can slow notebook rendering unless you intentionally resize or downsample them.

Summary

  • Use Markdown for simple static images in explanatory notebooks.
  • Use IPython.display.Image when image paths or sizes are decided by code.
  • Use Matplotlib when the image is part of analysis or needs annotation.
  • Prefer relative paths and repository-managed assets for portability.
  • Download important remote images locally instead of depending on a live URL.

Course illustration
Course illustration

All Rights Reserved.