The image_matrix()
function arranges a set of images in a grid.
Dimensions of the grid are determined by the shape of the input Numpy 2D array.
Each element of the input 2D array is an 2D or 3D Numpy array itself specifying either a grayscale image (2D array) or a color RGB(A) image (3D array).
For more information on image arrays please see the documentation of geom_imshow()
function.
The image_matrix()
function uses geom_imshow()
under the hood, so you may want to check these demos as well:
import numpy as np
from lets_plot import *
from lets_plot.bistro.im import image_matrix
LetsPlot.setup_html()
# Load image file.
from PIL import Image
import requests
from io import BytesIO
response = requests.get('https://github.com/JetBrains/lets-plot-docs/raw/master/source/examples/cookbook/images/fisher_boat.png')
image = Image.open(BytesIO(response.content))
img = np.asarray(image)
img.shape
(225, 225, 3)
Use the same image to fill the array elements.
M = 2 # rows
N = 3 # columns
X = np.empty([M, N], dtype=object)
X.fill(img)
image_matrix(X)
# Lets vary size of images in the matrix
X1 = np.empty([M, N], dtype=object)
for row in range(M):
for col in range(N):
v = (row + col + 1) * 10
X1[row][col] = img[v:-v,v:-v,:]
image_matrix(X1)
By default, luminance values in grayscale image will be scaled to [0-255] range using a linear scaler.
# Generate a grayscale image from an RGB image
# by selecting only one `R` channel:
img_gs = img[:,:,0]
img_gs.dtype
dtype('uint8')
For the demo purposes we will reduce the range of data in some of the images.
def _degrade(grayscale_img:np.ndarray, coef:float):
vmin = grayscale_img.min()
vmax = grayscale_img.max()
middle = vmin + (vmax - vmin) / 2
rows, cols = grayscale_img.shape
for row in range(rows):
for col in range(cols):
v = float(grayscale_img[row][col])
v_new = middle + (v - middle) * coef
grayscale_img[row][col] = int(v_new)
Now lets fill an 2D array with images, applying the _degrade()
function on each iteration.
The last image added is the one "degraded" the most.
X2 = np.empty([M, N], dtype=object)
img_copy = img_gs.copy()
for row in range(M):
for col in range(N):
X2[row][col] = img_copy
img_copy = img_copy.copy()
_degrade(img_copy, coef=.7)
print("[{}, {}] data range: [{}-{}]".format(row, col, img_copy.min(), img_copy.max()))
[0, 0] data range: [38-216] [0, 1] data range: [64-189] [0, 2] data range: [82-170] [1, 0] data range: [95-156] [1, 1] data range: [104-146] [1, 2] data range: [110-139]
image_matrix(X2)
image_matrix(X2, norm=False)
In case the image size is too small or too big to show, the displayed dimensions can be changed using the parameter scale
.
For example,digits
dataset from sklearn
package contains very small 8x8 pictures of digits.
# Load `digits` form sklearn.
from sklearn.datasets import load_digits
digits_bunch = load_digits()
digits_data = digits_bunch.data
# Create 4x4 ndarray containing the first 16 digits in from `digits` dataset.
cols = 4
rows = 4
X4 = np.empty((rows, cols), dtype=object)
for row in range(rows):
for col in range(cols):
i = row * cols + col;
digit_data = digits_data[i]
digit_img = digit_data.reshape(8, 8)
X4[row][col] = digit_img
X4[0][0].shape
(8, 8)
# NOTE: minimal plot size in Lets-Plot is 50x50 px.
# thus we actually don't see 8x8 images in their native dimensions here.
image_matrix(X4)
Each digit image is 8x8 px. Multiply by 15 to see 120x120 px images.
image_matrix(X4, scale=15)
Use values < 1. to see smaller images.
image_matrix(X, scale=.3)
cmap
parameter¶Use parameter cmap
to display grayscale images in pseudo-colors.
image_matrix(X2, cmap="viridis", norm=False)