Matplotlib: How to plot images instead of points?

There are two ways to do this.

  1. Plot the image using imshow with the extent kwarg set based on the location you want the image at.
  2. Use an OffsetImage inside an AnnotationBbox.

The first way is the easiest to understand, but the second has a large advantage. The annotation box approach will allow the image to stay at a constant size as you zoom in. Using imshow will tie the size of the image to the data coordinates of the plot.

Here’s an example of the second option:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
from matplotlib.cbook import get_sample_data

def main():
    x = np.linspace(0, 10, 20)
    y = np.cos(x)
    image_path = get_sample_data('ada.png')
    fig, ax = plt.subplots()
    imscatter(x, y, image_path, zoom=0.1, ax=ax)
    ax.plot(x, y)

def imscatter(x, y, image, ax=None, zoom=1):
    if ax is None:
        ax = plt.gca()
        image = plt.imread(image)
    except TypeError:
        # Likely already an array...
    im = OffsetImage(image, zoom=zoom)
    x, y = np.atleast_1d(x, y)
    artists = []
    for x0, y0 in zip(x, y):
        ab = AnnotationBbox(im, (x0, y0), xycoords="data", frameon=False)
    ax.update_datalim(np.column_stack([x, y]))
    return artists


enter image description here

Leave a Comment