Skip to content

Commit 2a1f49a

Browse files
authored
Merge pull request #4769 from plotly/add-base64-docs
Add performance doc
2 parents c9e8630 + f60f02c commit 2a1f49a

File tree

1 file changed

+78
-62
lines changed

1 file changed

+78
-62
lines changed

doc/python/webgl-vs-svg.md doc/python/performance.md

+78-62
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ jupyter:
66
extension: .md
77
format_name: markdown
88
format_version: '1.3'
9-
jupytext_version: 1.16.1
9+
jupytext_version: 1.16.4
1010
kernelspec:
1111
display_name: Python 3 (ipykernel)
1212
language: python
@@ -20,23 +20,28 @@ jupyter:
2020
name: python
2121
nbconvert_exporter: python
2222
pygments_lexer: ipython3
23-
version: 3.10.11
23+
version: 3.11.10
2424
plotly:
25-
description: Using WebGL for increased speed, improved interactivity, and the
26-
ability to plot even more data!
25+
description: Recommendations for increased speed, improved interactivity, and
26+
the ability to plot even more data!
2727
display_as: basic
2828
language: python
2929
layout: base
30-
name: WebGL vs SVG
30+
name: High Performance Visualization
3131
order: 14
32-
permalink: python/webgl-vs-svg/
33-
redirect_from: python/compare-webgl-svg/
32+
permalink: python/performance/
33+
redirect_from: python/webgl-vs-svg/
3434
thumbnail: thumbnail/webgl.jpg
3535
---
3636

37-
### SVG and canvas/WebGL: two browser capabilities for rendering
37+
## WebGL
3838

39-
`plotly` figures are rendered by web browsers, which broadly speaking have two families of capabilities for rendering graphics: the SVG API which supports vector rendering, and the Canvas API which supports raster rendering, and can exploit GPU hardware acceleration via a browser technology known as WebGL. Each `plotly` trace type is primarily rendered with either SVG or WebGL, although WebGL-powered traces also use some SVG. The following trace types use WebGL for part or all of the rendering:
39+
`plotly` figures are rendered by web browsers, which broadly speaking have two families of capabilities for rendering graphics:
40+
41+
- The SVG API, which supports vector rendering.
42+
- The Canvas API, which supports raster rendering, and can exploit GPU hardware acceleration via a browser technology known as WebGL.
43+
44+
Each `plotly` trace type is rendered with either SVG or WebGL. The following trace types use WebGL for rendering:
4045

4146
* Accelerated versions of SVG trace types: `scattergl`, `scatterpolargl`,
4247
* High-performance multidimensional trace types: `splom`, or `parcoords`
@@ -47,18 +52,18 @@ jupyter:
4752

4853
WebGL is a powerful technology for accelerating computation but comes with some strict limitations:
4954

50-
1. GPU requirement: WebGL is a GPU (graphics card) technology and therefore requires specific hardware which is available in most but not all cases and is supported by most but not all browsers
55+
1. GPU requirement: WebGL is a GPU (graphics card) technology and therefore requires specific hardware which is available in most but not all cases and is supported by most but not all browsers.
5156
2. Rasterization: WebGL-rendered data is drawn as a grid of pixels rather than as individual shapes, so can appear pixelated or fuzz in certain cases, and when exported to static file formats will appear pixelated on zoom. In addition: text rendering will differ between SVG and WebGL-powered traces.
52-
3. Context limits: browsers impose a strict limit on the number of WebGL "contexts" that any given web document can access. WebGL-powered traces in `plotly` can use multiple contexts in some cases but as a general rule, **it may not be possible to render more than 8 WebGL-involving figures on the same page at the same time.**
53-
4. Size limits: browsers impose hardware-dependent limits on the height and width of figures using WebGL which users may encounter with extremely large plots (e.g. tens of thousands of pixels of height)
57+
3. Context limits: browsers impose a strict limit on the number of WebGL "contexts" that any given web document can access. WebGL-powered traces in `plotly` can use multiple contexts in some cases but as a general rule, **it may not be possible to render more than 8 WebGL-involving figures on the same page at the same time.** See the following section, Multiple WebGL Contexts, for more details.
58+
4. Size limits: browsers impose hardware-dependent limits on the height and width of figures using WebGL which users may encounter with extremely large plots (e.g. tens of thousands of pixels of height).
5459

5560
In addition to the above limitations, the WebGL-powered version of certain SVG-powered trace types (`scattergl`, `scatterpolargl`) are not complete drop-in replacements for their SVG counterparts yet
56-
* Available symbols will differ
57-
* Area fills are not yet supported in WebGL
58-
* Range breaks on time-series axes are not yet supported
59-
* Axis range heuristics may differ
61+
* Available symbols will differ.
62+
* Area fills are not yet supported in WebGL.
63+
* Range breaks on time-series axes are not yet supported.
64+
* Axis range heuristics may differ.
6065

61-
### Multiple WebGL Contexts
66+
#### Multiple WebGL Contexts
6267

6368
*New in 5.19*
6469

@@ -72,12 +77,12 @@ To use it, in the environment where your Plotly figures are being rendered, load
7277

7378
In a Jupyter notebook environment that supports magic commands, you can load it with the [HTML magic command](https://ipython.readthedocs.io/en/stable/interactive/magics.html#cellmagic-html):
7479

75-
<!-- #region -->
80+
7681
```
7782
%%html
7883
<script src=“https://unpkg.com/virtual-webgl@1.0.6/src/virtual-webgl.js”></script>
7984
```
80-
<!-- #endregion -->
85+
8186

8287
### WebGL for Scatter Performance
8388

@@ -87,9 +92,9 @@ it is also possible to use [datashader](/python/datashader/).
8792

8893
### WebGL with Plotly Express
8994

90-
The `rendermode` argument to supported Plotly Express functions (e.g. `scatter` and `scatter_polar`) can be used to enable WebGL rendering.
95+
The `render_mode` argument to supported Plotly Express functions (e.g. `scatter` and `scatter_polar`) can be used to enable WebGL rendering.
9196

92-
> **Note** The default `rendermode` is `"auto"`, in which case Plotly Express will automatically set `rendermode="webgl"` if the input data is more than 1,000 rows long. If WebGL acceleration is *not* desired in this case, `rendermode` can be forced to `"svg"` for vectorized, if slower, rendering.
97+
> **Note** The default `render_mode` is `"auto"`, in which case Plotly Express will automatically set `render_mode="webgl"` if the input data is more than 1,000 rows long. In this case, WebGl can be disabled by setting `render_mode=svg`.
9398
9499
Here is an example that creates a 100,000 point scatter plot using Plotly Express with WebGL rendering explicitly enabled.
95100

@@ -98,6 +103,7 @@ import plotly.express as px
98103

99104
import pandas as pd
100105
import numpy as np
106+
101107
np.random.seed(1)
102108

103109
N = 100000
@@ -113,7 +119,7 @@ fig.show()
113119
```
114120

115121

116-
#### WebGL with 100,000 points with Graph Objects
122+
#### WebGL with 1,000,000 points with Graph Objects
117123

118124
If Plotly Express does not provide a good starting point, it is also possible to use [the more generic `go.Scattergl` class from `plotly.graph_objects`](/python/graph-objects/).
119125

@@ -122,9 +128,8 @@ import plotly.graph_objects as go
122128

123129
import numpy as np
124130

125-
N = 100000
131+
N = 1_000_000
126132

127-
# Create figure
128133
fig = go.Figure()
129134

130135
fig.add_trace(
@@ -143,58 +148,69 @@ fig.add_trace(
143148
fig.show()
144149
```
145150

146-
#### WebGL Rendering with 1 Million Points
151+
See https://plotly.com/python/reference/scattergl/ for more information and chart attribute options!
147152

148-
```python
149-
import plotly.graph_objects as go
153+
## NumPy and NumPy Convertible Arrays for Improved Performance
150154

151-
import numpy as np
155+
Improve the performance of generating Plotly figures that use a large number of data points by using NumPy arrays and other objects that Plotly can convert to NumPy arrays, such as Pandas and Polars Series.
152156

153-
N = 1000000
157+
Plotly.py uses Plotly.js for rendering, which supports typed arrays. In Plotly.py, NumPy array and NumPy-convertible arrays are base64 encoded before being passed to Plotly.js for rendering.
154158

155-
# Create figure
156-
fig = go.Figure()
159+
### Arrays and Data Types Supported
157160

158-
fig.add_trace(
159-
go.Scattergl(
160-
x = np.random.randn(N),
161-
y = np.random.randn(N),
162-
mode = 'markers',
163-
marker = dict(
164-
line = dict(
165-
width = 1,
166-
color = 'DarkSlateGrey')
167-
)
168-
)
169-
)
161+
The following types of objects in Python are supported for improved performance:
162+
163+
- Numpy `numpy.ndarray` objects.
164+
- Pandas Index, Pandas Series, Polars Series, and PyArrow Chunked Array objects.
165+
- Array objects that can be converted to `numpy.ndarray` objects. i.e., they implement `"__array__"` or `"__array_interface__"` and return a `numpy.ndarray`.
166+
167+
The following [array data types](https://numpy.org/devdocs/reference/arrays.scalars.html) are supported:
168+
169+
- float32
170+
- float64
171+
- int8
172+
- uint8
173+
- int16
174+
- uint16
175+
- int32
176+
- uint32
177+
178+
*If the array dtype is **int64** and **uint64**, often the default dtype for arrays in NumPy when no dtype is specified, those dtypes will be changed to other types internally by Plotly.py where possible. When working with NumPY directly, you can [specify the `dtype`](https://numpy.org/doc/stable/user/basics.types.html#array-types-and-conversions-between-types) when creating `ndarray` objects.
179+
180+
### Unsupported Attributes
181+
182+
Arrays passed to attributes with the following names are not supported:
183+
184+
`geojson`, `layers`, and `range`.
170185

171-
fig.show()
172-
```
173186

174-
#### WebGL with many traces
187+
### Example with NumPy Arrays
188+
189+
Here, we use NumPy arrays with a `go.Scatter3d` figure.
175190

176191
```python
177192
import plotly.graph_objects as go
178-
179193
import numpy as np
180194

181-
fig = go.Figure()
195+
np.random.seed(1)
182196

183-
trace_num = 10
184-
point_num = 5000
185-
for i in range(trace_num):
186-
fig.add_trace(
187-
go.Scattergl(
188-
x = np.linspace(0, 1, point_num),
189-
y = np.random.randn(point_num)+(i*5)
190-
)
191-
)
197+
# Number of data points
198+
N = 10000
199+
200+
# Generate random data
201+
x = np.random.randn(N)
202+
y = np.random.randn(N).astype('float32')
203+
z = np.random.randint(size=N, low=0, high=256, dtype='uint8')
204+
c = np.random.randint(size=N, low=-10, high=10, dtype='int8')
192205

193-
fig.update_layout(showlegend=False)
206+
fig = go.Figure(data=[go.Scatter3d(
207+
x=x,
208+
y=y,
209+
z=z,
210+
marker=dict(color=c),
211+
mode='markers',
212+
opacity=0.2
213+
)])
194214

195215
fig.show()
196216
```
197-
198-
### Reference
199-
200-
See https://plotly.com/python/reference/scattergl/ for more information and chart attribute options!

0 commit comments

Comments
 (0)