Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib: How to plot images instead of points?

I want to read a list of images into Python/Matplotlib and then plot this images instead of other markers (like points) in a graph. I have tried with imshow but I didn't succeed, because I cannot shift the image to another position and scale it appropriately. Maybe somebody has a good idea : ) It should look somehow like this! (Without the Spongebob, but with very serious data of course!)

like image 650
Anna Christine Avatar asked Mar 21 '14 18:03

Anna Christine


People also ask

How do I display multiple images in one figure correctly in matplotlib?

The easiest way to display multiple images in one figure is use figure(), add_subplot(), and imshow() methods of Matplotlib. The approach which is used to follow is first initiating fig object by calling fig=plt. figure() and then add an axes object to the fig by calling add_subplot() method.


2 Answers

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)     plt.show()  def imscatter(x, y, image, ax=None, zoom=1):     if ax is None:         ax = plt.gca()     try:         image = plt.imread(image)     except TypeError:         # Likely already an array...         pass     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)         artists.append(ax.add_artist(ab))     ax.update_datalim(np.column_stack([x, y]))     ax.autoscale()     return artists  main() 

enter image description here

like image 103
Joe Kington Avatar answered Sep 17 '22 13:09

Joe Kington


If you want different images:

This is now the first reply when googling "matplotlib scatter with images". If you're like me and actually need to plot different images on each image, try this minimalied example instead. Just be sure to input your own images.

import matplotlib.pyplot as plt from matplotlib.offsetbox import OffsetImage, AnnotationBbox  def getImage(path, zoom=1):     return OffsetImage(plt.imread(path), zoom=zoom)  paths = [     'a.jpg',     'b.jpg',     'c.jpg',     'd.jpg',     'e.jpg']      x = [0,1,2,3,4] y = [0,1,2,3,4]  fig, ax = plt.subplots() ax.scatter(x, y)   for x0, y0, path in zip(x, y,paths):     ab = AnnotationBbox(getImage(path), (x0, y0), frameon=False)     ax.add_artist(ab) 

enter image description here

like image 31
Mitchell van Zuylen Avatar answered Sep 19 '22 13:09

Mitchell van Zuylen