20

I want to display 2 PNG images in iPython side by side.

My code to do this is:

from IPython.display import Image, HTML, display

img_A = '\path\to\img_A.png'
img_B = '\path\to\img_B.png'

display(HTML("<table><tr><td><img src=img_A></td><td><img src=img_B></td></tr></table>"))

But it doesn't output the images, and instead only displays placeholders for the 2 images:

enter image description here

I tried the following as well:

s = """<table>
<tr>
<th><img src="%s"/></th>
<th><img src="%s"/></th>
</tr></table>"""%(img_A, img_B)
t=HTML(s)
display(t)

But the result is the same:

enter image description here

The images are in the path for sure, because I verified by displaying them in a pop up:

plt.imshow(img_A)
plt.imshow(img_B)

and they do appear in the pop ups.

How do I make the 2 images appear side by side in iPython?

Kristada673
  • 3,512
  • 6
  • 39
  • 93

6 Answers6

21

You can try using matplotlib. You can read image to numpy array by using mpimg.imread (documentation) from matplotlib, then you can use subplots (documentation) and for creating two columns for figures and finally imshow (documetation) to display images.

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from matplotlib import rcParams

%matplotlib inline

# figure size in inches optional
rcParams['figure.figsize'] = 11 ,8

# read images
img_A = mpimg.imread('\path\to\img_A.png')
img_B = mpimg.imread('\path\to\img_B.png')

# display images
fig, ax = plt.subplots(1,2)
ax[0].imshow(img_A)
ax[1].imshow(img_B)
zr0gravity7
  • 2,917
  • 1
  • 12
  • 33
niraj
  • 17,498
  • 4
  • 33
  • 48
16

matplotlib is a very good tool for plotting but I found it very heavy and slow for scenarios where I simply need a fast and easy way to display bigger number of images.
To solve this I'm using IPyPlot package:

import ipyplot

ipyplot.plot_images(images_list, max_images=20, img_width=150)

You would get a plot similar to this:
enter image description here

Karol Żak
  • 2,158
  • 20
  • 24
  • in my case, empty images are displayed, even if the path is correct and other methods for reading the image run fine. – Antonio Sesto Mar 12 '22 at 06:48
  • I don't understand the syntax `images[labels == 'tents']` and I wasn't able to find information by googling, can you explain how it works ? – Damien Oct 26 '22 at 11:12
  • 1
    @Damien don't mind that. You can just pass a list of images as a parameter. In case of that syntax I simply filter the list of `labels` by looking for string `tents` which returns a list of True and False values adequately and that's what I use for slicing of selecting specific images from my `images` list – Karol Żak Oct 26 '22 at 13:03
6

Kind of late but i found out about this over here

You can do it via Hbox. Hbox is a special container where you can add widgets. It aims at providing an efficient way to lay out, align and distribute space among items in a given space. Although its a bit cumbersome to define so many elements just to display 2 images you can add a lot more functionality like sliders, dropdown menus as well as buttons making your Jupiter notebook more interactive.

import IPython.display as display
import ipywidgets as widgets

img1=open('path_to_image','rb').read()
wi1 = widgets.Image(value=img1, format='jpg', width=300, height=400)
img2=open('path_to_image','rb').read()
wi2 = widgets.Image(value=img2, format='jpg', width=300, height=400)
a=[wi1,wi2]
wid=widgets.HBox(a)
display.display(wid)
Shreyas H.V
  • 109
  • 1
  • 3
  • The above method works best for png images(it essentially converts the image into binary and then displays it as per my knowledge). Found what you need here --> https://stackoverflow.com/questions/60640375/displaying-gifs-in-jupyter-notebook-using-widgets – Shreyas H.V May 09 '21 at 18:27
2

This easy solution worked great for me:

from IPython.display import Video, Image, HTML, display

image_path1 = "/myfolder/my_img1.jpg"
image_path2 = "/myfolder/my_img2.jpg"


HTML(f"""
    <div class="row">
            <img src={image_path1} style="width:30%"> </img>
            <img src={image_path1} style="width:53.2%"> </img>
    </div>
    """)

I put in different widths for if you have a portrait and a landscape picture, but that is up to you depending on the images and the aspect ratios.

n4321d
  • 1,059
  • 2
  • 12
  • 31
1

For some guys who may want to place an image and a text snippet side by side(adapted from this answer):

import base64
from IPython.display import HTML, display
b64_img =  base64.b64encode(open('./path', 'rb').read()).decode('ascii')
txt = "sjfa;\nakd;f\nsdfa"
display(HTML(f"""
    <div class="row">
    <img style="float:left;margin-right:30px;" src="data:image/jpeg;base64,{b64_img}" width="400" height="300" />
    <div style="font-size:10px;white-space:pre;">{txt}</div>
    </div>
    """))
Lerner Zhang
  • 6,184
  • 2
  • 49
  • 66
0

It should be like this:

from IPython.display import Image, HTML, display

img_A = '\path\to\img_A.png'
img_B = '\path\to\img_B.png'

display(HTML("<table><tr><td><img src={0}></td><td><img src={1}></td></tr></table>".format(image_A,img_B)))

You mistook the variable name as variable itself.