Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add performance doc #4769

Merged
merged 25 commits into from
Nov 4, 2024
Merged
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7770164
add examples using base64
archmoj Jan 9, 2024
c2d755e
remove example + make small changes to metadata
LiamConnors Sep 17, 2024
d0bc21b
add back correct examples
LiamConnors Sep 17, 2024
fb0a5d8
add content for numpy arrays
LiamConnors Sep 18, 2024
49ae498
fix typo
LiamConnors Sep 19, 2024
589d105
rename file
LiamConnors Sep 19, 2024
79afc5c
update titles and link
LiamConnors Sep 19, 2024
af1c4a4
fix typo and shorten content
LiamConnors Sep 19, 2024
170d7f9
Update numpy-arrays.md
LiamConnors Sep 19, 2024
7a67f81
merge performance content
LiamConnors Sep 23, 2024
f75521c
add intro and restructure svg intro
LiamConnors Sep 23, 2024
c895f10
Update webgl-vs-svg.md
LiamConnors Sep 23, 2024
77d7aa3
Update webgl-vs-svg.md
LiamConnors Oct 3, 2024
c1e43e7
Update webgl-vs-svg.md
LiamConnors Oct 3, 2024
bdfd6af
Update doc/python/webgl-vs-svg.md
LiamConnors Oct 3, 2024
8a3769c
Update doc/python/webgl-vs-svg.md
LiamConnors Oct 3, 2024
cf7ac59
change order of dtypes + mention specifying dtype in numpy
LiamConnors Oct 10, 2024
02a9b28
add link to numpy reference docs
LiamConnors Oct 22, 2024
6c6c27b
Merge branch 'master' into add-base64-docs
LiamConnors Nov 1, 2024
56bb8fc
remove extra webgl examples
LiamConnors Nov 4, 2024
cdd7839
shorten webgl content
LiamConnors Nov 4, 2024
9ee6b26
small edits + remove extra example
LiamConnors Nov 4, 2024
1325ac1
rename file
LiamConnors Nov 4, 2024
24021f3
add update to types of series
LiamConnors Nov 4, 2024
f60f02c
Merge branch 'version-6-migration' into add-base64-docs
LiamConnors Nov 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 78 additions & 62 deletions doc/python/webgl-vs-svg.md → doc/python/performance.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be great to combine https://plotly.com/python/datashader/ into this page too!

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jupyter:
extension: .md
format_name: markdown
format_version: '1.3'
jupytext_version: 1.16.1
jupytext_version: 1.16.4
kernelspec:
display_name: Python 3 (ipykernel)
language: python
Expand All @@ -20,23 +20,28 @@ jupyter:
name: python
nbconvert_exporter: python
pygments_lexer: ipython3
version: 3.10.11
version: 3.11.10
plotly:
description: Using WebGL for increased speed, improved interactivity, and the
ability to plot even more data!
description: Recommendations for increased speed, improved interactivity, and
the ability to plot even more data!
display_as: basic
language: python
layout: base
name: WebGL vs SVG
name: High Performance Visualization
order: 14
permalink: python/webgl-vs-svg/
redirect_from: python/compare-webgl-svg/
permalink: python/performance/
redirect_from: python/webgl-vs-svg/
thumbnail: thumbnail/webgl.jpg
---

### SVG and canvas/WebGL: two browser capabilities for rendering
## WebGL

`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:
`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.
- 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 rendered with either SVG or WebGL. The following trace types use WebGL for rendering:

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

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

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
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.
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.
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.**
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)
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.
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).

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
* Available symbols will differ
* Area fills are not yet supported in WebGL
* Range breaks on time-series axes are not yet supported
* Axis range heuristics may differ
* Available symbols will differ.
* Area fills are not yet supported in WebGL.
* Range breaks on time-series axes are not yet supported.
* Axis range heuristics may differ.

### Multiple WebGL Contexts
#### Multiple WebGL Contexts

*New in 5.19*

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

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):

<!-- #region -->

```
%%html
<script src=“https://unpkg.com/[email protected]/src/virtual-webgl.js”></script>
```
<!-- #endregion -->


### WebGL for Scatter Performance

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

### WebGL with Plotly Express

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

> **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.
> **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`.

Here is an example that creates a 100,000 point scatter plot using Plotly Express with WebGL rendering explicitly enabled.

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

import pandas as pd
import numpy as np

np.random.seed(1)

N = 100000
Expand All @@ -113,7 +119,7 @@ fig.show()
```


#### WebGL with 100,000 points with Graph Objects
#### WebGL with 1,000,000 points with Graph Objects

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/).

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

import numpy as np

N = 100000
N = 1_000_000

# Create figure
fig = go.Figure()

fig.add_trace(
Expand All @@ -143,58 +148,69 @@ fig.add_trace(
fig.show()
```

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

```python
import plotly.graph_objects as go
## NumPy and NumPy Convertible Arrays for Improved Performance

import numpy as np
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.

N = 1000000
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.

# Create figure
fig = go.Figure()
### Arrays and Data Types Supported

fig.add_trace(
go.Scattergl(
x = np.random.randn(N),
y = np.random.randn(N),
mode = 'markers',
marker = dict(
line = dict(
width = 1,
color = 'DarkSlateGrey')
)
)
)
The following types of objects in Python are supported for improved performance:

- Numpy `numpy.ndarray` objects.
- Pandas Index, Pandas Series, Polars Series, and PyArrow Chunked Array objects.
- Array objects that can be converted to `numpy.ndarray` objects. i.e., they implement `"__array__"` or `"__array_interface__"` and return a `numpy.ndarray`.

The following [array data types](https://numpy.org/devdocs/reference/arrays.scalars.html) are supported:

- float32
- float64
- int8
- uint8
- int16
- uint16
- int32
- uint32

*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.

### Unsupported Attributes

Arrays passed to attributes with the following names are not supported:

`geojson`, `layers`, and `range`.

fig.show()
```

#### WebGL with many traces
### Example with NumPy Arrays

Here, we use NumPy arrays with a `go.Scatter3d` figure.

```python
import plotly.graph_objects as go

import numpy as np

fig = go.Figure()
np.random.seed(1)

trace_num = 10
point_num = 5000
for i in range(trace_num):
fig.add_trace(
go.Scattergl(
x = np.linspace(0, 1, point_num),
y = np.random.randn(point_num)+(i*5)
)
)
# Number of data points
N = 10000

# Generate random data
x = np.random.randn(N)
y = np.random.randn(N).astype('float32')
z = np.random.randint(size=N, low=0, high=256, dtype='uint8')
c = np.random.randint(size=N, low=-10, high=10, dtype='int8')

fig.update_layout(showlegend=False)
fig = go.Figure(data=[go.Scatter3d(
x=x,
y=y,
z=z,
marker=dict(color=c),
mode='markers',
opacity=0.2
)])

fig.show()
```

### Reference

See https://plotly.com/python/reference/scattergl/ for more information and chart attribute options!