If you want the image at the corner of your actual figure (rather than the corner of your axis), look into figimage.

Perhaps something like this? (using PIL to read the image):

import matplotlib.pyplot as plt
import Image
import numpy as np

im = Image.open('/home/jofer/logo.png')
height = im.size[1]

# We need a float array between 0-1, rather than
# a uint8 array between 0-255
im = np.array(im).astype(np.float) / 255

fig = plt.figure()

plt.plot(np.arange(10), 4 * np.arange(10))

# With newer (1.0) versions of matplotlib, you can 
# use the "zorder" kwarg to make the image overlay
# the plot, rather than hide behind it... (e.g. zorder=10)
fig.figimage(im, 0, fig.bbox.ymax - height)

# (Saving with the same dpi as the screen default to
#  avoid displacing the logo image)
fig.savefig('/home/jofer/temp.png', dpi=80)

plt.show()

Another option, if you'd like to have the image be a fixed fraction of the figure's width/height is to create a "dummy" axes and place the image in it with imshow. This way the image's size and position is independent of DPI and the figure's absolute size:

import matplotlib.pyplot as plt
from matplotlib.cbook import get_sample_data

im = plt.imread(get_sample_data('grace_hopper.jpg'))

fig, ax = plt.subplots()
ax.plot(range(10))

# Place the image in the upper-right corner of the figure
#--------------------------------------------------------
# We're specifying the position and size in _figure_ coordinates, so the image
# will shrink/grow as the figure is resized. Remove "zorder=-1" to place the
# image in front of the axes.
newax = fig.add_axes([0.8, 0.8, 0.2, 0.2], anchor='NE', zorder=-1)
newax.imshow(im)
newax.axis('off')

plt.show()

Answer from Joe Kington on Stack Overflow
Top answer
1 of 2
61

If you want the image at the corner of your actual figure (rather than the corner of your axis), look into figimage.

Perhaps something like this? (using PIL to read the image):

import matplotlib.pyplot as plt
import Image
import numpy as np

im = Image.open('/home/jofer/logo.png')
height = im.size[1]

# We need a float array between 0-1, rather than
# a uint8 array between 0-255
im = np.array(im).astype(np.float) / 255

fig = plt.figure()

plt.plot(np.arange(10), 4 * np.arange(10))

# With newer (1.0) versions of matplotlib, you can 
# use the "zorder" kwarg to make the image overlay
# the plot, rather than hide behind it... (e.g. zorder=10)
fig.figimage(im, 0, fig.bbox.ymax - height)

# (Saving with the same dpi as the screen default to
#  avoid displacing the logo image)
fig.savefig('/home/jofer/temp.png', dpi=80)

plt.show()

Another option, if you'd like to have the image be a fixed fraction of the figure's width/height is to create a "dummy" axes and place the image in it with imshow. This way the image's size and position is independent of DPI and the figure's absolute size:

import matplotlib.pyplot as plt
from matplotlib.cbook import get_sample_data

im = plt.imread(get_sample_data('grace_hopper.jpg'))

fig, ax = plt.subplots()
ax.plot(range(10))

# Place the image in the upper-right corner of the figure
#--------------------------------------------------------
# We're specifying the position and size in _figure_ coordinates, so the image
# will shrink/grow as the figure is resized. Remove "zorder=-1" to place the
# image in front of the axes.
newax = fig.add_axes([0.8, 0.8, 0.2, 0.2], anchor='NE', zorder=-1)
newax.imshow(im)
newax.axis('off')

plt.show()

2 of 2
12

There is now a much easier way, using the new inset_axes command (matplotlib >3.0 required).

This command allows one to define a new set of axes as a child of an existing axes object. The advantage of this is that you can define your inset axes in whatever units you please, like axes fraction or data coordinates, using the appropriate transform expression.

So here's a code example:

# Imports
import matplotlib.pyplot as plt
import matplotlib as mpl

# read image file
with mpl.cbook.get_sample_data(r"C:\path\to\file\image.png") as file:
arr_image = plt.imread(file, format='png')

# Draw image
axin = ax.inset_axes([105,-145,40,40],transform=ax.transData)    # create new inset axes in data coordinates
axin.imshow(arr_image)
axin.axis('off')

The advantage of this method is that your image will scale automatically as your axes get rescaled!

🌐
Towards Data Science
towardsdatascience.com › home › latest › how to add an image to a matplotlib plot in python
How to Add an Image to a Matplotlib Plot in Python | Towards Data Science
January 28, 2025 - According to the shape of the logo, the plot has 720 and 520 as limits on the X and Y-axis respectively as illustrated below: Displaying image data using Matplotlib. Image by Author. To add the logo image to the bar plot, I created an OffsetBox (a simple container artist) and passed the logo inside of it.
🌐
Matplotlib
matplotlib.org › stable › tutorials › images.html
Image tutorial — Matplotlib 3.11.2 documentation
This interface maintains global ... various plot settings. The alternative is the explicit, which is more suitable for large application development. For an explanation of the tradeoffs between the implicit and explicit interfaces see Matplotlib Application Interfaces (APIs) and the Quick start guide to start using the explicit interface. For now, let's get on with the implicit approach: from PIL import Image import ...
🌐
Python Graph Gallery
python-graph-gallery.com › 513-add-logo-matplotlib
How to insert an image into a Matplotlib chart
This post explains how to insert an image into your matplotlib plot using the PIL and io libraries. Two use cases are considered: your image beeing stored locally or somewhere on the web. ... Font ColorwhiteFont Opacity100%Font Size100%Font FamilyArialText ShadownoneBackground ColorblackBackground Opacity50%Window ColorblackWindow Opacity0% ... Adding ...
🌐
Medium
medium.com › data-science › how-to-add-an-image-to-a-matplotlib-plot-in-python-76098becaf53
How to Add an Image to a Matplotlib Plot in Python | by Himalaya Shrestha | TDS Archive | Medium
June 14, 2022 - According to the shape of the logo, the plot has 720 and 520 as limits on the X and Y-axis respectively as illustrated below: ... Displaying image data using Matplotlib. Image by Author. To add the logo image to the bar plot, I created an OffsetBox (a simple container artist) and passed the logo inside of it.
🌐
TutorialsPoint
tutorialspoint.com › how-to-insert-a-small-image-on-the-corner-of-a-plot-with-matplotlib
How to insert a small image on the corner of a plot with Matplotlib?
May 7, 2021 - Using subplots() method, create a figure and add a set of subplots. Plot a line on the current axis. Create newax (new axis) to show the image array (Step 1). Turn off the newly created axis, created for an image insert. To display the figure, use show() method. import matplotlib.pyplot as ...
🌐
Ramiro
ramiro.org › notebook › matplotlib-branding
Adding Branding Images to Plots in Matplotlib • Jupyter Notebook
%matplotlib inline %load_ext signature import matplotlib as mpl import matplotlib.gridspec as gridspec import matplotlib.pyplot as plt import numpy as np import pandas as pd import helpers mpl.style.use('ggplot') logo = plt.imread('img/ramiro.org-branding.png') ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2010', periods=1000)).cumsum() In the first example we simply call the plot method on the Pandas Series object created above and receive a AxesSubplot object in return. We then set the title on that object and add the image in the lower left corner with low opacity so it does not hide features of the graph.
🌐
Moonbooks
moonbooks.org › Articles › How-to-insert-an-image-a-picture-or-a-photo-in-a-matplotlib-figure
How to insert an image (a picture or a photo) in a matplotlib figure
August 24, 2022 - from matplotlib.offsetbox import TextArea, DrawingArea, OffsetImage, AnnotationBbox import matplotlib.pyplot as plt import matplotlib.image as mpimg fig, ax = plt.subplots() ax.set_xlim(0, 1) ax.set_ylim(0, 1) arr_lena = mpimg.imread('Lenna.png') imagebox = OffsetImage(arr_lena, zoom=0.2) ab = AnnotationBbox(imagebox, (0.4, 0.6)) ax.add_artist(ab) plt.grid() plt.draw() plt.savefig('add_picture_matplotlib_figure.png',bbox_inches='tight') plt.show()
Find elsewhere
🌐
Medium
medium.com › analytics-vidhya › how-to-plot-image-and-text-on-matplotlib-91d7f23a3043
How to plot image and text using Python matplotlib | by shotin | Analytics Vidhya | Medium
September 8, 2020 - Use “add_artist”, just like this. from matplotlib.offsetbox import OffsetImage, AnnotationBboxfor i, record in records.iterrows(): image = plt.imread('image/' + record.Team + '.png') ax.add_artist( #ax can be added image as artist.
🌐
YouTube
youtube.com › jie jenn
How to insert image icon in Matplotlib - YouTube
In this lesson, we will do a simple exercise learning how to insert image annotation in a #matplotlib graph. Buy Me a Coffee? Your support is much appreciate...
Published: January 21, 2020
Views: 545
🌐
Matplotlib
matplotlib.org › stable › gallery › images_contours_and_fields › image_demo.html
Many ways to plot images — Matplotlib 3.11.2 documentation
You can specify whether images should be plotted with the array origin x[0, 0] in the upper left or lower right by using the origin parameter. You can also control the default setting image.origin in your matplotlibrc file. For more on this topic see the complete guide on origin and extent.
🌐
SukhbinderSingh.com
sukhbinder.wordpress.com › 2022 › 05 › 25 › put-an-image-behind-your-matplotlib-plots
Put an Image Behind your matplotlib plots – SukhbinderSingh.com
August 16, 2022 - You want to add pretty graphics in the back of your data. How to do this with matplotlib? Solution · import numpy as np import matplotlib.pyplot as plt # Path to the image fpath =r"C:\Users\sukhbinder.singh\Desktop\day.jpg" # Read the image img = plt.imread(fpath) # Plot the image fig, ax = plt.subplots() ax.imshow(img) a, b, c,d = plt.axis('off') # Now plot your appropriatly scalled data.
🌐
Matplotlib
matplotlib.org › stable › tutorials › introductory › images.html
Image tutorial — Matplotlib 3.7.2 documentation
August 13, 2021 - This interface maintains global state, and is very useful for quickly and easily experimenting with various plot settings. The alternative is the explicit, which is more suitable for large application development. For an explanation of the tradeoffs between the implicit and explicit interfaces see Matplotlib Application Interfaces (APIs) and the Quick start guide to start using the explicit interface. For now, let's get on with the implicit approach: import matplotlib.pyplot as plt import numpy as np from PIL import Image
🌐
LabEx
labex.io › tutorials › matplotlib-overlay-image-on-matplotlib-plot-49029
Overlay Image on Matplotlib Plot | Python Tutorials | LabEx
This way, we can easily apply the same effect to different plots. Create a new cell in your notebook and enter the following code: def add_image_overlay(fig, image_path, x_pos=25, y_pos=25, alpha=0.5, zorder=3): """ Add an image overlay to a matplotlib figure.
🌐
Matplotlib
matplotlib.org › stable › gallery › images_contours_and_fields › watermark_image.html
Watermark image — Matplotlib 3.11.2 documentation
Go to the end to download the full example code. Overlay an image on a plot by moving it to the front (zorder=3) and making it semi-transparent (alpha=0.7).
Top answer
1 of 2
28

This demo from the matplotlib gallery shows how to insert pictures, draw lines to them, etc. I'll post the image from the gallery, and you can follow the link to see the code.

And here's the code (from version 2.1.2):

import matplotlib.pyplot as plt
import numpy as np

from matplotlib.patches import Circle
from matplotlib.offsetbox import (TextArea, DrawingArea, OffsetImage,
                                  AnnotationBbox)
from matplotlib.cbook import get_sample_data


if 1:
    fig, ax = plt.subplots()

    # Define a 1st position to annotate (display it with a marker)
    xy = (0.5, 0.7)
    ax.plot(xy[0], xy[1], ".r")

    # Annotate the 1st position with a text box ('Test 1')
    offsetbox = TextArea("Test 1", minimumdescent=False)

    ab = AnnotationBbox(offsetbox, xy,
                        xybox=(-20, 40),
                        xycoords='data',
                        boxcoords="offset points",
                        arrowprops=dict(arrowstyle="->"))
    ax.add_artist(ab)

    # Annotate the 1st position with another text box ('Test')
    offsetbox = TextArea("Test", minimumdescent=False)

    ab = AnnotationBbox(offsetbox, xy,
                        xybox=(1.02, xy[1]),
                        xycoords='data',
                        boxcoords=("axes fraction", "data"),
                        box_alignment=(0., 0.5),
                        arrowprops=dict(arrowstyle="->"))
    ax.add_artist(ab)

    # Define a 2nd position to annotate (don't display with a marker this time)
    xy = [0.3, 0.55]

    # Annotate the 2nd position with a circle patch
    da = DrawingArea(20, 20, 0, 0)
    p = Circle((10, 10), 10)
    da.add_artist(p)

    ab = AnnotationBbox(da, xy,
                        xybox=(1.02, xy[1]),
                        xycoords='data',
                        boxcoords=("axes fraction", "data"),
                        box_alignment=(0., 0.5),
                        arrowprops=dict(arrowstyle="->"))

    ax.add_artist(ab)

    # Annotate the 2nd position with an image (a generated array of pixels)
    arr = np.arange(100).reshape((10, 10))
    im = OffsetImage(arr, zoom=2)
    im.image.axes = ax

    ab = AnnotationBbox(im, xy,
                        xybox=(-50., 50.),
                        xycoords='data',
                        boxcoords="offset points",
                        pad=0.3,
                        arrowprops=dict(arrowstyle="->"))

    ax.add_artist(ab)

    # Annotate the 2nd position with another image (a Grace Hopper portrait)
    fn = get_sample_data("grace_hopper.png", asfileobj=False)
    arr_img = plt.imread(fn, format='png')

    imagebox = OffsetImage(arr_img, zoom=0.2)
    imagebox.image.axes = ax

    ab = AnnotationBbox(imagebox, xy,
                        xybox=(120., -80.),
                        xycoords='data',
                        boxcoords="offset points",
                        pad=0.5,
                        arrowprops=dict(
                            arrowstyle="->",
                            connectionstyle="angle,angleA=0,angleB=90,rad=3")
                        )

    ax.add_artist(ab)

    # Fix the display limits to see everything
    ax.set_xlim(0, 1)
    ax.set_ylim(0, 1)

    plt.show()
2 of 2
20

If I understand the question correctly, then perhaps this may help:

import scipy
import pylab
fig = pylab.figure()
axplot = fig.add_axes([0.07,0.25,0.90,0.70])
axplot.plot(scipy.randn(100))
numicons = 8
for k in range(numicons):
    axicon = fig.add_axes([0.07+0.11*k,0.05,0.1,0.1])
    axicon.imshow(scipy.rand(4,4),interpolation='nearest')
    axicon.set_xticks([])
    axicon.set_yticks([])
fig.show()
fig.savefig('iconsbelow.png')

🌐
Life Cycle Geo
lifecyclegeo.com › home › adding figure insets and logos in python
Adding Figure Insets and Logos in Python - Life Cycle Geo
December 14, 2021 - import matplotlib.pyplot as plt im2 = imageio.imread('lcg_logo_inline_RGB.jpg') fig, axs = plt.subplots(figsize=(5,5)) newax = fig.add_axes([0.01, 0.01, 2, 2], anchor='SE') newax.imshow(im2) newax.axis('off') Here, the arguments for the fig.add_axes correspond to the position of the logo relative to your figure (x1 = 0.01 and y1 = 0.01) and the width and height of the logo (2,2).
🌐
Iditect
iditect.com › faq › python › adding-a-background-image-to-a-plot-in-python.html
Adding a background image to a plot in python
import matplotlib.pyplot as plt from matplotlib.offsetbox import OffsetImage, AnnotationBbox # Load background image img = plt.imread('background_image.png') # Plot data plt.scatter(x_data, y_data) # Add background image plt.imshow(img, extent=[xmin, xmax, ymin, ymax], aspect='auto') plt.show()