Skip to content

Commit 46a3a33

Browse files
Merge pull request #163 from plotly/image
new tutorial on displaying image data
2 parents 7756589 + bd06f3b commit 46a3a33

File tree

2 files changed

+213
-25
lines changed

2 files changed

+213
-25
lines changed

python/images.md

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ jupyter:
66
extension: .md
77
format_name: markdown
88
format_version: '1.1'
9-
jupytext_version: 1.1.7
9+
jupytext_version: 1.1.1
1010
kernelspec:
1111
display_name: Python 3
1212
language: python
@@ -20,7 +20,7 @@ jupyter:
2020
name: python
2121
nbconvert_exporter: python
2222
pygments_lexer: ipython3
23-
version: 3.6.5
23+
version: 3.7.3
2424
plotly:
2525
description: How to add images to charts as background images or logos.
2626
display_as: file_settings
@@ -30,10 +30,13 @@ jupyter:
3030
order: 31
3131
permalink: python/images/
3232
thumbnail: thumbnail/images.png
33+
v4upgrade: true
3334
---
3435

3536
#### Add a Background Image
3637

38+
In this page we explain how to add static, non-interactive images as background, logo or annotation images to a figure. For exploring image data in interactive charts, see the [tutorial on displaying image data](/python/imshow).
39+
3740
```python
3841
import plotly.graph_objects as go
3942

@@ -46,8 +49,7 @@ fig.add_trace(
4649
)
4750

4851
# Add images
49-
fig.update_layout(
50-
images=[
52+
fig.add_layout_image(
5153
go.layout.Image(
5254
source="https://images.plot.ly/language-icons/api-home/python-logo.png",
5355
xref="x",
@@ -59,7 +61,6 @@ fig.update_layout(
5961
sizing="stretch",
6062
opacity=0.5,
6163
layer="below")
62-
]
6364
)
6465

6566
# Set templates
@@ -112,14 +113,14 @@ fig.add_trace(
112113
)
113114

114115
# Add image
115-
fig.update_layout(
116-
images=[dict(
116+
fig.add_layout_image(
117+
dict(
117118
source="https://raw.githubusercontent.com/cldougl/plot_images/add_r_img/vox.png",
118119
xref="paper", yref="paper",
119120
x=1, y=1.05,
120121
sizex=0.2, sizey=0.2,
121122
xanchor="right", yanchor="bottom"
122-
)],
123+
)
123124
)
124125

125126
# update layout properties
@@ -171,30 +172,26 @@ for (x, y), n in zip(simulated_absorptions, names):
171172
fig.add_trace(go.Scatter(x=x, y=y, name=n))
172173

173174
# Add images
174-
fig.update_layout(
175-
images=[go.layout.Image(
175+
fig.add_layout_image(
176+
go.layout.Image(
176177
source="https://raw.githubusercontent.com/michaelbabyn/plot_data/master/benzene.png",
177-
xref="paper",
178-
yref="paper",
179178
x=0.75,
180179
y=0.65,
181-
sizex=0.3,
182-
sizey=0.3,
183-
xanchor="right",
184-
yanchor="bottom"
185-
), go.layout.Image(
180+
))
181+
fig.add_layout_image(go.layout.Image(
186182
source="https://raw.githubusercontent.com/michaelbabyn/plot_data/master/naphthalene.png",
187-
xref="paper",
188-
yref="paper",
189183
x=0.9,
190184
y=0.3,
185+
)
186+
)
187+
fig.update_layout_images(dict(
188+
xref="paper",
189+
yref="paper",
191190
sizex=0.3,
192191
sizey=0.3,
193192
xanchor="right",
194193
yanchor="bottom"
195-
)
196-
]
197-
)
194+
))
198195

199196
# Add annotations
200197
fig.update_layout(
@@ -277,8 +274,8 @@ fig.update_yaxes(
277274
)
278275

279276
# Add image
280-
fig.update_layout(
281-
images=[go.layout.Image(
277+
fig.add_layout_image(
278+
go.layout.Image(
282279
x=0,
283280
sizex=img_width * scale_factor,
284281
y=img_height * scale_factor,
@@ -288,7 +285,7 @@ fig.update_layout(
288285
opacity=1.0,
289286
layer="below",
290287
sizing="stretch",
291-
source="https://raw.githubusercontent.com/michaelbabyn/plot_data/master/bridge.jpg")]
288+
source="https://raw.githubusercontent.com/michaelbabyn/plot_data/master/bridge.jpg")
292289
)
293290

294291
# Configure other layout

python/imshow.md

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
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

Comments
 (0)