geom_imshow()
displays an image specified by 2D or 3D Numpy array.
Whether the image is grayscale or color depends on the shape of the image array:
For example, you can create an RGB image array from a PNG file using PIL
and io
packages.
geom_raster()
on the other hand is a regular ggplot
graphic layer wich takes a data-frame as the input
and applies the aesthetic mappings as specified by the aes()
function.
import numpy as np
import pandas as pd
from lets_plot import *
LetsPlot.setup_html()
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)
M x N x 3 ndarray
specifies a color RGB image.
ggplot() + geom_imshow(img)
M x N ndarray
specifies a grayscale image.
We will generate a grayscale image from RGB image above
by selecting only its R
channel.
img_gs = img[:,:,0]
img_gs.shape
(225, 225)
ggplot() + geom_imshow(img_gs)
ggplot() + geom_imshow(img_gs, cmap="magma")
geom_raster()
¶The geom_raster()
function also can display image. But unlike geom_imshow()
, geom_raster()
doesn't accept ndarray
as an input.
As a regular ggplot
graphic layer, geom_raster()
requires an observations-style input data and aestetic mapping.
This is not very convenient when the data is originally in the form of ndarray
. On the other hand, aesthetic mapping and color scales might come in handy when rendering an image.
Lets transform the image data to a data-frame suitable for geom_raster()
.
# reshape 3-dimentional ndarray to 2-dimentional long-form ndarray
# and then to data frame with columns x,y,r,g,b
cols, rows, _ = img.shape
img_lf = img.reshape(cols * rows, -1)
img_df = pd.DataFrame(img_lf,columns=['r','g','b'])
X_mesh, Y_mesh = np.meshgrid(np.arange(rows), np.arange(cols))
img_df['x'] = X_mesh.reshape(-1)
img_df['y'] = Y_mesh.reshape(-1)[::-1]
# Pack color components values to 24-bit RGB values
c_fill = img_df.apply(lambda row: ((int(row['r'] * 255) << 16) +
(int(row['g'] * 255) << 8) +
int(row['b'] * 255)),
axis=1)
# Show image in pseudo colors with only few gradations
(ggplot(img_df) + geom_raster(aes('x', 'y', fill=c_fill), show_legend=False)
+ scale_fill_brewer()
+ ggtitle('Raster geom with brewer palette') + ggsize(800,500))