简体   繁体   中英

Python - plotting multiple images on x-y coordinates

Given a set of images, and (x,y) coordinates associated with each image, I'd like to create a "composite" plot of my set of images, each at its (x,y) coordinate.

For instance, given the following set, where each item in the list is a (x, y, image) tuple:

images = [(0,0,'image1.jpg'), (0,1,'image2.jpg'), (1,0,'image3.jpg)]

I'd like to create a plot where the image corresponding to image1.jpg is plotted on an xy plot at coordinates (0,0), the image corresponding to image2.jpg is plotted at (0, 1), etc...

I had been tackling this with a very manual approach using PIL, where I would do a lot of manual calculation, scaling, and even hand-drawing axes and such to "paste" the composite image together. It works, but my code is a mess, the resulting image isn't too pretty, and it seems like the PIL library has some portability issues.

Is there a way to do this with perhaps Matplotlib? I tried searching through their examples, but none of them were quite what I was looking for, and there's so much you can do with Matplotlib that it makes my head spin.

If anyone has any pointers that might get me started, it would be highly appreciated.

For reference, I'm trying to target Python 2.7, though I'm savvy enough to translate any 3.x code.

Self edit: perhaps this is what I'm looking for:

Placing Custom Images in a Plot Window--as custom data markers or to annotate those markers

EDIT: see accepted answer. For the sake of posterity, here's a basic working example. I also added black borders around the images, which gives it a nice touch:

import matplotlib.pyplot as plt
from matplotlib._png import read_png
from matplotlib.pylab import Rectangle, gca

def main():
    ax = plt.subplot(111)
    ax.set_autoscaley_on(False)
    ax.set_autoscalex_on(False)
    ax.set_ylim([0,10])
    ax.set_xlim([0,10])

    imageData = read_png('image1.png')
    plt.imshow(imageData, extent=[0,2,0,1])
    gca().add_patch(Rectangle((0,0),2, 1, facecolor=(0,0,0,0)))

    imageData = read_png('image2.png')
    plt.imshow(imageData, extent=[2,4,1,2])
    gca().add_patch(Rectangle((2,1),2, 1, facecolor=(0,0,0,0)))

    imageData = read_png('image4.png')
    plt.imshow(imageData, extent=[4,6,2,3])
    gca().add_patch(Rectangle((4,2),2, 1, facecolor=(0,0,0,0)))

    plt.draw()
    plt.savefig('out.png', dpi=300)

To control where an image is shown in data-space use the extent kwarg of imshow which sets the location of the [left, right, bottom, top] edges. Something like:

list_of_corners = [(left0, right0, bottom0, top0), ...]
list_of_images = [im0, im1, ...]
ax, fig = plt.subplots(1, 1)

for extent, img in zip(list_of_corners, list_of_images):
    ax.imshow(img, extent=extent, ...)

should do the trick.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM