|
| 1 | +--- |
| 2 | +jupyter: |
| 3 | + jupytext: |
| 4 | + notebook_metadata_filter: all |
| 5 | + text_representation: |
| 6 | + extension: .md |
| 7 | + format_name: markdown |
| 8 | + format_version: '1.1' |
| 9 | + jupytext_version: 1.1.1 |
| 10 | + kernelspec: |
| 11 | + display_name: Python 3 |
| 12 | + language: python |
| 13 | + name: python3 |
| 14 | + language_info: |
| 15 | + codemirror_mode: |
| 16 | + name: ipython |
| 17 | + version: 3 |
| 18 | + file_extension: .py |
| 19 | + mimetype: text/x-python |
| 20 | + name: python |
| 21 | + nbconvert_exporter: python |
| 22 | + pygments_lexer: ipython3 |
| 23 | + version: 3.7.3 |
| 24 | + plotly: |
| 25 | + description: How to display image data in Python with Plotly. |
| 26 | + display_as: scientific |
| 27 | + has_thumbnail: true |
| 28 | + ipynb: ~notebook_demo/34 |
| 29 | + language: python |
| 30 | + layout: base |
| 31 | + name: Imshow |
| 32 | + order: 3 |
| 33 | + page_type: example_index |
| 34 | + permalink: python/imshow/ |
| 35 | + redirect_from: python/imshow/ |
| 36 | + thumbnail: thumbnail/imshow.jpg |
| 37 | + v4upgrade: true |
| 38 | +--- |
| 39 | + |
| 40 | +This tutorial shows how to display and explore image data. If you would like |
| 41 | +instead a logo or static image, use `go.layout.Image` as explained |
| 42 | +[here](/python/images). |
| 43 | + |
| 44 | +### Displaying RBG image data with px.imshow |
| 45 | + |
| 46 | +`px.imshow` displays multichannel (RGB) or single-channel ("grayscale") image data. |
| 47 | + |
| 48 | +```python |
| 49 | +import plotly.express as px |
| 50 | +import numpy as np |
| 51 | +img_rgb = np.array([[[255, 0, 0], [0, 255, 0], [0, 0, 255]], |
| 52 | + [[0, 255, 0], [0, 0, 255], [255, 0, 0]] |
| 53 | + ], dtype=np.uint8) |
| 54 | +fig = px.imshow(img_rgb) |
| 55 | +fig.show() |
| 56 | +``` |
| 57 | + |
| 58 | +### Read image arrays from image files |
| 59 | + |
| 60 | +In order to create a numerical array to be passed to `px.imshow`, you can use a third-party library like [PIL](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.open), [scikit-image](https://scikit-image.org/docs/dev/user_guide/getting_started.html) or [opencv](https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_gui/py_image_display/py_image_display.html). 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`. |
| 61 | + |
| 62 | +```python |
| 63 | +import plotly.express as px |
| 64 | +from skimage import io |
| 65 | +img = io.imread('https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Crab_Nebula.jpg/240px-Crab_Nebula.jpg') |
| 66 | +fig = px.imshow(img) |
| 67 | +fig.show() |
| 68 | +``` |
| 69 | + |
| 70 | +```python |
| 71 | +import plotly.express as px |
| 72 | +from skimage import data |
| 73 | +img = data.astronaut() |
| 74 | +fig = px.imshow(img) |
| 75 | +fig.show() |
| 76 | +``` |
| 77 | + |
| 78 | +### Display single-channel 2D image as grayscale |
| 79 | + |
| 80 | +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](/python/templates/)). |
| 81 | + |
| 82 | +```python |
| 83 | +import plotly.express as px |
| 84 | +import numpy as np |
| 85 | +img = np.arange(15**2).reshape((15, 15)) |
| 86 | +fig = px.imshow(img) |
| 87 | +fig.show() |
| 88 | +``` |
| 89 | + |
| 90 | +### Choose the colorscale to display a single-channel image |
| 91 | + |
| 92 | + |
| 93 | +```python |
| 94 | +import plotly.express as px |
| 95 | +import numpy as np |
| 96 | +img = np.arange(100).reshape((10, 10)) |
| 97 | +fig = px.imshow(img, color_continuous_scale='gray') |
| 98 | +fig.show() |
| 99 | +``` |
| 100 | + |
| 101 | +### Display multichannel image data with go.Image |
| 102 | + |
| 103 | +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`](/python/heatmaps). |
| 104 | + |
| 105 | +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](/python/images). |
| 106 | + |
| 107 | +```python |
| 108 | +import plotly.graph_objects as go |
| 109 | +img_rgb = [[[255, 0, 0], [0, 255, 0], [0, 0, 255]], |
| 110 | + [[0, 255, 0], [0, 0, 255], [255, 0, 0]]] |
| 111 | +fig = go.Figure(go.Image(z=img_rgb)) |
| 112 | +fig.show() |
| 113 | +``` |
| 114 | + |
| 115 | +### Defining the data range covered by the color range with zmin and zmax |
| 116 | + |
| 117 | +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. |
| 118 | + |
| 119 | +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: |
| 120 | +- for integer data types, `zmin` and `zmax` correspond to the extreme values of the data type, for example 0 and 255 for `uint8`, 0 and 65535 for `uint16`, etc. |
| 121 | +- 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 2**16 - 1 and 2**32 -1). |
| 122 | + |
| 123 | +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`. |
| 124 | + |
| 125 | +```python |
| 126 | +import plotly.express as px |
| 127 | +from skimage import data |
| 128 | +img = data.astronaut() |
| 129 | +# Increase contrast by clipping the data range between 50 and 200 |
| 130 | +fig = px.imshow(img, zmin=50, zmax=200) |
| 131 | +# We customize the hovertemplate to show both the data and the color values |
| 132 | +# See https://plot.ly/python/hover-text-and-formatting/#customize-tooltip-text-with-a-hovertemplate |
| 133 | +fig.update_traces(hovertemplate="x: %{x} <br> y: %{y} <br> z: %{z} <br> color: %{color}") |
| 134 | +fig.show() |
| 135 | +``` |
| 136 | + |
| 137 | +```python |
| 138 | +import plotly.express as px |
| 139 | +from skimage import data |
| 140 | +img = data.astronaut() |
| 141 | +# Stretch the contrast of the red channel only, resulting in a more red image |
| 142 | +fig = px.imshow(img, zmin=[50, 0, 0], zmax=[200, 255, 255]) |
| 143 | +fig.show() |
| 144 | +``` |
| 145 | + |
| 146 | +### Ticks and margins around image data |
| 147 | + |
| 148 | +```python |
| 149 | +import plotly.express as px |
| 150 | +from skimage import data |
| 151 | +img = data.astronaut() |
| 152 | +fig = px.imshow(img) |
| 153 | +fig.update_layout(width=400, height=400, margin=dict(l=10, r=10, b=10, t=10)) |
| 154 | +fig.update_xaxes(showticklabels=False).update_yaxes(showticklabels=False) |
| 155 | +fig.show() |
| 156 | +``` |
| 157 | + |
| 158 | +### Combining image charts and other traces |
| 159 | + |
| 160 | +```python |
| 161 | +import plotly.express as px |
| 162 | +import plotly.graph_objects as go |
| 163 | +from skimage import data |
| 164 | +img = data.camera() |
| 165 | +fig = px.imshow(img, color_continuous_scale='gray') |
| 166 | +fig.add_trace(go.Contour(z=img, showscale=False, |
| 167 | + contours=dict(start=0, end=70, size=70, coloring='lines'), |
| 168 | + line_width=2)) |
| 169 | +fig.add_trace(go.Scatter(x=[230], y=[100], marker=dict(color='red', size=16))) |
| 170 | +fig.show() |
| 171 | +``` |
| 172 | + |
| 173 | +### Displaying an image and the histogram of color values |
| 174 | + |
| 175 | +```python |
| 176 | +from plotly.subplots import make_subplots |
| 177 | +from skimage import data |
| 178 | +img = data.chelsea() |
| 179 | +fig = make_subplots(1, 2) |
| 180 | +# We use go.Image because subplots require traces, whereas px functions return a figure |
| 181 | +fig.add_trace(go.Image(z=img), 1, 1) |
| 182 | +for channel, color in enumerate(['red', 'green', 'blue']): |
| 183 | + fig.add_trace(go.Histogram(x=img[..., channel].ravel(), opacity=0.5, |
| 184 | + marker_color=color, name='%s channel' %color), 1, 2) |
| 185 | +fig.update_layout(height=400) |
| 186 | +fig.show() |
| 187 | +``` |
| 188 | + |
| 189 | +#### Reference |
| 190 | +See https://plot.ly/python/reference/#image for more information and chart attribute options! |
| 191 | + |
0 commit comments