jupyter | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
This tutorial shows how to display and explore image data. If you would like
instead a logo or static image, use go.layout.Image
as explained
here.
px.imshow
displays multichannel (RGB) or single-channel ("grayscale") image data.
import plotly.express as px
import numpy as np
img_rgb = np.array([[[255, 0, 0], [0, 255, 0], [0, 0, 255]],
[[0, 255, 0], [0, 0, 255], [255, 0, 0]]
], dtype=np.uint8)
fig = px.imshow(img_rgb)
fig.show()
In order to create a numerical array to be passed to px.imshow
, you can use a third-party library like PIL, scikit-image or opencv. We show below how to open an image from a file with skimage.io.imread
, and alternatively how to load a demo image from skimage.data
.
import plotly.express as px
from skimage import io
img = io.imread('https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Crab_Nebula.jpg/240px-Crab_Nebula.jpg')
fig = px.imshow(img)
fig.show()
import plotly.express as px
from skimage import data
img = data.astronaut()
fig = px.imshow(img)
fig.show()
For a 2D image, px.imshow
uses a colorscale to map scalar data to colors. The default colorscale is the one of the active template (see the tutorial on templates).
import plotly.express as px
import numpy as np
img = np.arange(15**2).reshape((15, 15))
fig = px.imshow(img)
fig.show()
You can customize the continuous color scale just like with any other Plotly Express function:
import plotly.express as px
import numpy as np
img = np.arange(100).reshape((10, 10))
fig = px.imshow(img, color_continuous_scale='Viridis')
fig.show()
You can use this to make the image grayscale as well:
import plotly.express as px
import numpy as np
img = np.arange(100).reshape((10, 10))
fig = px.imshow(img, color_continuous_scale='gray')
fig.show()
See the continuous color and cartesian axes pages for more details.
import plotly.express as px
from skimage import data
img = data.camera()
fig = px.imshow(img, color_continuous_scale='gray')
fig.update_layout(coloraxis_showscale=False)
fig.update_xaxes(showticklabels=False)
fig.update_yaxes(showticklabels=False)
fig.show()
You can use the x
, y
and labels
arguments to customize the display of a heatmap, and use .update_xaxes()
to move the x axis tick labels to the top:
import plotly.express as px
data=[[1, 25, 30, 50, 1], [20, 1, 60, 80, 30], [30, 60, 1, 5, 20]]
fig = px.imshow(data,
labels=dict(x="Day of Week", y="Time of Day", color="Productivity"),
x=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
y=['Morning', 'Afternoon', 'Evening']
)
fig.update_xaxes(side="top")
fig.show()
xarrays are labeled arrays (with labeled axes and coordinates). If you pass an xarray image to px.imshow
, its axes labels and coordinates will be used for axis titles. If you don't want this behavior, you can pass img.values
which is a NumPy array if img
is an xarray. Alternatively, you can override axis titles hover labels and colorbar title using the labels
attribute, as above.
import plotly.express as px
import xarray as xr
# Load xarray from dataset included in the xarray tutorial
airtemps = xr.tutorial.open_dataset('air_temperature').air.sel(lon=250.0)
fig = px.imshow(airtemps.T, color_continuous_scale='RdBu_r', origin='lower')
fig.show()
For xarrays, by default px.imshow
does not constrain pixels to be square, since axes often correspond to different physical quantities (e.g. time and space), contrary to a plain camera image where pixels are square (most of the time). If you want to impose square pixels, set the parameter aspect
to "equal" as below.
import plotly.express as px
import xarray as xr
airtemps = xr.tutorial.open_dataset('air_temperature').air.isel(time=500)
colorbar_title = airtemps.attrs['var_desc'] + '<br>(%s)'%airtemps.attrs['units']
fig = px.imshow(airtemps, color_continuous_scale='RdBu_r', aspect='equal')
fig.show()
It is also possible to use the go.Image
trace from the low-level graph_objects
API in order to display image data. Note that go.Image
only accepts multichannel images. For single images, use go.Heatmap
.
Note that the go.Image
trace is different from the go.layout.Image
class, which can be used for adding background images or logos to figures.
import plotly.graph_objects as go
img_rgb = [[[255, 0, 0], [0, 255, 0], [0, 0, 255]],
[[0, 255, 0], [0, 0, 255], [255, 0, 0]]]
fig = go.Figure(go.Image(z=img_rgb))
fig.show()
The data range and color range are mapped together using the parameters zmin
and zmax
, which correspond respectively to the data values mapped to black [0, 0, 0]
and white [255, 255, 255]
, or to the extreme colors of the colorscale in the case on single-channel data.
For single-channel data, the defaults values of zmin
and zmax
used by px.imshow
and go.Heatmap
are the extrema of the data range. For multichannel data, px.imshow
and go.Image
use slightly different default values for zmin
and zmax
. For go.Image
, the default value is zmin=[0, 0, 0]
and zmax=[255, 255, 255]
, no matter the data type. On the other hand, px.imshow
adapts the default zmin
and zmax
to the data type:
- for integer data types,
zmin
andzmax
correspond to the extreme values of the data type, for example 0 and 255 foruint8
, 0 and 65535 foruint16
, etc. - for float numbers, the maximum value of the data is computed, and zmax is 1 if the max is smaller than 1, 255 if the max is smaller than 255, etc. (with higher thresholds 216 - 1 and 232 -1).
These defaults can be overriden by setting the values of zmin
and zmax
. For go.Image
, zmin
and zmax
need to be given for all channels, whereas it is also possible to pass a scalar value (used for all channels) to px.imshow
.
import plotly.express as px
from skimage import data
img = data.astronaut()
# Increase contrast by clipping the data range between 50 and 200
fig = px.imshow(img, zmin=50, zmax=200)
# We customize the hovertemplate to show both the data and the color values
# See https://plot.ly/python/hover-text-and-formatting/#customize-tooltip-text-with-a-hovertemplate
fig.update_traces(hovertemplate="x: %{x} <br> y: %{y} <br> z: %{z} <br> color: %{color}")
fig.show()
import plotly.express as px
from skimage import data
img = data.astronaut()
# Stretch the contrast of the red channel only, resulting in a more red image
fig = px.imshow(img, zmin=[50, 0, 0], zmax=[200, 255, 255])
fig.show()
import plotly.express as px
from skimage import data
img = data.astronaut()
fig = px.imshow(img)
fig.update_layout(width=400, height=400, margin=dict(l=10, r=10, b=10, t=10))
fig.update_xaxes(showticklabels=False).update_yaxes(showticklabels=False)
fig.show()
import plotly.express as px
import plotly.graph_objects as go
from skimage import data
img = data.camera()
fig = px.imshow(img, color_continuous_scale='gray')
fig.add_trace(go.Contour(z=img, showscale=False,
contours=dict(start=0, end=70, size=70, coloring='lines'),
line_width=2))
fig.add_trace(go.Scatter(x=[230], y=[100], marker=dict(color='red', size=16)))
fig.show()
from plotly.subplots import make_subplots
from skimage import data
img = data.chelsea()
fig = make_subplots(1, 2)
# We use go.Image because subplots require traces, whereas px functions return a figure
fig.add_trace(go.Image(z=img), 1, 1)
for channel, color in enumerate(['red', 'green', 'blue']):
fig.add_trace(go.Histogram(x=img[..., channel].ravel(), opacity=0.5,
marker_color=color, name='%s channel' %color), 1, 2)
fig.update_layout(height=400)
fig.show()
Arrays of rasterized values build by datashader can be visualized using imshow. See the plotly and datashader tutorial for examples on how to use plotly and datashader.
See https://plot.ly/python/reference/#image for more information and chart attribute options!