Skip to content

Commit 25a77f3

Browse files
jonmmeasenicholas-esterernicolaskruchten
authored
Add Kaleido image export support (#2613)
* add engine kwarg to to_image/write_image functions * Update Image renderers with engine parameter * Don't auto-start orca when image renderer is activated because now we might not end up using orca. * Added kaleido engine tests * Python 2.7 mock compatibility * Update CHANGELOG.md * Add kaleido test that actually calls Kaleido and checks that the resulting bytes are reasonable * Update image export documentation to recommend and describe Kaleido * Add engine docstring to figure image export methods * Change kaleido conda channel to plotly since it most likely won't be available on conda-forge initially * Conda package renamed from kaleido -> python-kaleido * in README: indicate that Keleido is new and improved and orca is legacy * Add Kaleido note to orca-management section * Fix JPEG typo * Merge "Install Dependency" sections and better explain that Kaleido is new and recommended * Replace Orca with plotly.py when discussing supported image export formats Co-authored-by: NickE <[email protected]> Co-authored-by: Nicolas Kruchten <[email protected]>
1 parent 9bac518 commit 25a77f3

File tree

12 files changed

+535
-86
lines changed

12 files changed

+535
-86
lines changed

Diff for: CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
66

77
### Added
88

9+
- Added image export support using [Kaleido](https://github.com/plotly/Kaleido). The image export backend can be configured using the new `engine` argument to `plotly.io.to_image` and `plotly.io.write_image`. The `engine` argument may be set to `"kaleido"`, `"orca"`, or `"auto"`. The default is `engine="auto"`, in which case the Kaleido backend is enabled if the `kaleido` package from PyPI is installed, otherwise Orca is used. ([#2613](https://github.com/plotly/plotly.py/pull/2613)).
910
- `px.NO_COLOR` constant to override wide-form color assignment in Plotly Express ([#2614](https://github.com/plotly/plotly.py/pull/2614))
1011
- `facet_row_spacing` and `facet_col_spacing` added to Plotly Express cartesian 2d functions ([#2614](https://github.com/plotly/plotly.py/pull/2614))
1112
- `base` added to Plotly Express `bar` and `bar_polar` functions
@@ -30,7 +31,6 @@ This project adheres to [Semantic Versioning](http://semver.org/).
3031
- Updated Plotly.js to version 1.54.5. See the [plotly.js CHANGELOG](https://github.com/plotly/plotly.js/blob/v1.54.5/CHANGELOG.md) for more information.
3132
- `add_traces()` now accepts bare `int`-like values for `rows`/`cols` as well as lists thereof ([#2546](https://github.com/plotly/plotly.py/pull/2546)), with thanks to [@MCBoarder289](https://github.com/MCBoarder289) for the contribution!
3233

33-
3434
### Fixed
3535

3636
- `row`/`col` now accept `int`-like values, not strictly `int` values ([#2451](https://github.com/plotly/plotly.py/pull/2451)), with thanks to [@MCBoarder289](https://github.com/MCBoarder289) for the contribution!

Diff for: README.md

+18-4
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,26 @@ jupyter labextension install @jupyter-widgets/jupyterlab-manager plotlywidget@4.
133133

134134
Please check out our [Troubleshooting guide](https://plotly.com/python/troubleshooting/) if you run into any problems with JupyterLab.
135135

136-
### Static Image Export
136+
### Static Image Export with Kaleido
137137

138138
plotly.py supports static image export using the `to_image` and `write_image`
139-
functions in the `plotly.io` package. This functionality requires the
140-
installation of the plotly [orca](https://github.com/plotly/orca) command line utility and the
141-
[`psutil`](https://github.com/giampaolo/psutil) Python package.
139+
functions in the `plotly.io` module. This functionality requires the
140+
[`kaleido`](https://github.com/plotly/Kaleido) package which can be installed
141+
using pip...
142+
143+
```
144+
$ pip install -U kaleido
145+
```
146+
147+
or conda.
148+
```
149+
$ conda install -c plotly python-kaleido
150+
```
151+
152+
### Static Image Export with Orca
153+
While Kaleido is now the recommended image export approach because it is easier to install and more widely compatible, image export can also be supported
154+
by the legacy [orca](https://github.com/plotly/orca) command line utility and the
155+
[`psutil`](https://github.com/giampaolo/psutil) Python package.
142156

143157
These dependencies can both be installed using conda:
144158

Diff for: doc/python/orca-management.md

+61-5
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,72 @@ jupyter:
3434
---
3535

3636
### Overview
37-
This section covers the lower-level details of how plotly.py uses orca to perform static image generation. Please refer to the [Static Image Export](/python/static-image-export/) section for general information on creating static images from plotly.py figures.
37+
This section covers the lower-level details of how plotly.py can use orca to perform static image generation.
3838

39-
### What is Orca?
39+
> Orca is no longer the recommended way to do static image export. We now recommend Kaleido, as described in the [Static Image Export](/python/static-image-export/) section .
40+
41+
Please refer to the [Static Image Export](/python/static-image-export/) section for general information on creating static images from plotly.py figures.
42+
43+
### What is orca?
4044
Orca is an [Electron](https://electronjs.org/) application that inputs plotly figure specifications and converts them into static images. Orca can run as a command-line utility or as a long-running server process. In order to provide the fastest possible image export experience, plotly.py launches orca in server mode, and communicates with it over a local port. See https://github.com/plotly/orca for more information.
4145

4246
By default, plotly.py launches the orca server process the first time an image export operation is performed, and then leaves it running until the main Python process exits. Because of this, the first image export operation in an interactive session will typically take a couple of seconds, but then all subsequent export operations will be significantly faster, since the server is already running.
4347

48+
### Installing orca
49+
There are 3 general approaches to installing orca and its Python dependencies.
50+
51+
##### conda
52+
Using the [conda](https://conda.io/docs/) package manager, you can install these dependencies in a single command:
53+
```
54+
$ conda install -c plotly plotly-orca==1.2.1 psutil requests
55+
```
56+
57+
**Note:** Even if you do not want to use conda to manage your Python dependencies, it is still useful as a cross platform tool for managing native libraries and command-line utilities (e.g. git, wget, graphviz, boost, gcc, nodejs, cairo, etc.). For this use-case, start with [Miniconda](https://conda.io/miniconda.html) (~60MB) and tell the installer to add itself to your system `PATH`. Then run `conda install plotly-orca==1.2.1` and the orca executable will be available system wide.
58+
59+
##### npm + pip
60+
You can use the [npm](https://www.npmjs.com/get-npm) package manager to install `orca` (and its `electron` dependency), and then use pip to install `psutil`:
61+
62+
```
63+
$ npm install -g [email protected] orca
64+
$ pip install psutil requests
65+
```
66+
67+
##### Standalone Binaries + pip
68+
If you are unable to install conda or npm, you can install orca as a precompiled binary for your operating system. Follow the instructions in the orca [README](https://github.com/plotly/orca) to install orca and add it to your system `PATH`. Then use pip to install `psutil`.
69+
70+
```
71+
$ pip install psutil requests
72+
```
73+
74+
<!-- #region -->
75+
### Install orca on Google Colab
76+
```
77+
!pip install plotly>=4.7.1
78+
!wget https://github.com/plotly/orca/releases/download/v1.2.1/orca-1.2.1-x86_64.AppImage -O /usr/local/bin/orca
79+
!chmod +x /usr/local/bin/orca
80+
!apt-get install xvfb libgtk2.0-0 libgconf-2-4
81+
```
82+
83+
Once this is done you can use this code to make, show and export a figure:
84+
85+
```python
86+
import plotly.graph_objects as go
87+
fig = go.Figure( go.Scatter(x=[1,2,3], y=[1,3,2] ) )
88+
fig.write_image("fig1.svg")
89+
fig.write_image("fig1.png")
90+
```
91+
92+
The files can then be downloaded with:
93+
94+
```python
95+
from google.colab import files
96+
files.download('fig1.svg')
97+
files.download('fig1.png')
98+
```
99+
<!-- #endregion -->
44100

45101
### Create a Figure
46-
Now let's create a simple scatter plot with 100 random points of variying color and size.
102+
Now let's create a simple scatter plot with 100 random points of varying color and size.
47103

48104
```python
49105
import plotly.graph_objects as go
@@ -198,7 +254,7 @@ In addition to the `executable` property, the `plotly.io.orca.config` object can
198254
- **`timeout`**: The number of seconds of inactivity required before the orca server is shut down. For example, if timeout is set to 20, then the orca server will shutdown once is has not been used for at least 20 seconds. If timeout is set to `None` (the default), then the server will not be automatically shut down due to inactivity.
199255
- **`default_width`**: The default pixel width to use on image export.
200256
- **`default_height`**: The default pixel height to use on image export.
201-
- **`default_scale`**: The default image scale facor applied on image export.
257+
- **`default_scale`**: The default image scale factor applied on image export.
202258
- **`default_format`**: The default image format used on export. One of `"png"`, `"jpeg"`, `"webp"`, `"svg"`, `"pdf"`, or `"eps"`.
203259
- **`mathjax`**: Location of the MathJax bundle needed to render LaTeX characters. Defaults to a CDN location. If fully offline export is required, set this to a local MathJax bundle.
204260
- **`topojson`**: Location of the topojson files needed to render choropleth traces. Defaults to a CDN location. If fully offline export is required, set this to a local directory containing the [Plotly.js topojson files](https://github.com/plotly/plotly.js/tree/master/dist/topojson).
@@ -207,4 +263,4 @@ In addition to the `executable` property, the `plotly.io.orca.config` object can
207263

208264

209265
### Saving Configuration Settings
210-
Configuration options can optionally be saved to the `~/.plotly/` directory by calling the `plotly.io.config.save()` method. Saved setting will be automatically loaded at the start of future sessions.
266+
Configuration options can optionally be saved to the `~/.plotly/` directory by calling the `plotly.io.config.save()` method. Saved setting will be automatically loaded at the start of future sessions.

Diff for: doc/python/static-image-export.md

+51-52
Original file line numberDiff line numberDiff line change
@@ -37,39 +37,27 @@ jupyter:
3737

3838
### Interactive vs Static Export
3939

40-
Plotly figures are interactive when viewed in a web browser: you can hover over data points, pan and zoom axes, and show and hide traces by clicking or double-clicking on the legend. You can export figures either to static image file formats like PNG, JEPG, SVG or PDF or you can [export them to HTML files which can be opened in a browser and remain interactive](/python/interactive-html-export/). This page explains how to do the former.
40+
Plotly figures are interactive when viewed in a web browser: you can hover over data points, pan and zoom axes, and show and hide traces by clicking or double-clicking on the legend. You can export figures either to static image file formats like PNG, JPEG, SVG or PDF or you can [export them to HTML files which can be opened in a browser and remain interactive](/python/interactive-html-export/). This page explains how to do the former.
4141

4242

4343
<!-- #region -->
4444
#### Install Dependencies
45-
Static image generation requires the [orca](https://github.com/plotly/orca) commandline utility and the [psutil](https://github.com/giampaolo/psutil) and [requests](https://2.python-requests.org/en/master/) Python libraries. There are 3 general approach to installing these dependencies.
46-
47-
##### conda
48-
Using the [conda](https://conda.io/docs/) package manager, you can install these dependencies in a single command:
45+
Static image generation requires either [Kaleido](https://github.com/plotly/Kaleido) (recommended) or [orca](https://github.com/plotly/orca) (legacy). The `kaleido` package can be installed using pip...
4946
```
50-
$ conda install -c plotly plotly-orca==1.2.1 psutil requests
47+
$ pip install -U kaleido
5148
```
5249

53-
**Note:** Even if you do not want to use conda to manage your Python dependencies, it is still useful as a cross platform tool for managing native libraries and command-line utilities (e.g. git, wget, graphviz, boost, gcc, nodejs, cairo, etc.). For this use-case, start with [Miniconda](https://conda.io/miniconda.html) (~60MB) and tell the installer to add itself to your system `PATH`. Then run `conda install plotly-orca==1.2.1` and the orca executable will be available system wide.
54-
55-
##### npm + pip
56-
You can use the [npm](https://www.npmjs.com/get-npm) package manager to install `orca` (and its `electron` dependency), and then use pip to install `psutil`:
57-
58-
```
59-
$ npm install -g [email protected] orca
60-
$ pip install psutil requests
50+
or conda.
6151
```
52+
$ conda install -c plotly python-kaleido
53+
```
6254

63-
##### Standalone Binaries + pip
64-
If you are unable to install conda or npm, you can install orca as a precompiled binary for your operating system. Follow the instructions in the orca [README](https://github.com/plotly/orca) to install orca and add it to your system `PATH`. Then use pip to install `psutil`.
55+
While Kaleido is now the recommended approach, image export can also be supported by the legacy [orca](https://github.com/plotly/orca) command line utility. See the [Orca Management](/python/orca-management/) section for instructions on installing, configuring, and troubleshooting orca.
6556

66-
```
67-
$ pip install psutil requests
68-
```
6957
<!-- #endregion -->
7058

7159
### Create a Figure
72-
Now let's create a simple scatter plot with 100 random points of variying color and size.
60+
Now let's create a simple scatter plot with 100 random points of varying color and size.
7361

7462
```python
7563
import plotly.graph_objects as go
@@ -116,7 +104,7 @@ If you are running this notebook live, click to [open the output directory](./im
116104
#### Raster Formats: PNG, JPEG, and WebP
117105

118106

119-
Orca can output figures to several raster image formats including **PNG**, ...
107+
plotly.py can output figures to several raster image formats including **PNG**, ...
120108

121109
```python
122110
fig.write_image("images/fig1.png")
@@ -137,7 +125,7 @@ fig.write_image("images/fig1.webp")
137125
#### Vector Formats: SVG and PDF...
138126

139127

140-
Orca can also output figures in several vector formats including **SVG**, ...
128+
plotly.py can also output figures in several vector formats including **SVG**, ...
141129

142130
```python
143131
fig.write_image("images/fig1.svg")
@@ -157,33 +145,6 @@ fig.write_image("images/fig1.eps")
157145

158146
**Note:** It is important to note that any figures containing WebGL traces (i.e. of type `scattergl`, `heatmapgl`, `contourgl`, `scatter3d`, `surface`, `mesh3d`, `scatterpolargl`, `cone`, `streamtube`, `splom`, or `parcoords`) that are exported in a vector format will include encapsulated rasters, instead of vectors, for some parts of the image.
159147

160-
<!-- #region -->
161-
### Install orca on Google Colab
162-
```
163-
!pip install plotly>=4.7.1
164-
!wget https://github.com/plotly/orca/releases/download/v1.2.1/orca-1.2.1-x86_64.AppImage -O /usr/local/bin/orca
165-
!chmod +x /usr/local/bin/orca
166-
!apt-get install xvfb libgtk2.0-0 libgconf-2-4
167-
```
168-
169-
Once this is done you can use this code to make, show and export a figure:
170-
171-
```python
172-
import plotly.graph_objects as go
173-
fig = go.Figure( go.Scatter(x=[1,2,3], y=[1,3,2] ) )
174-
fig.write_image("fig1.svg")
175-
fig.write_image("fig1.png")
176-
```
177-
178-
The files can then be downloaded with:
179-
180-
```python
181-
from google.colab import files
182-
files.download('fig1.svg')
183-
files.download('fig1.png')
184-
```
185-
<!-- #endregion -->
186-
187148
### Get Image as Bytes
188149
The `plotly.io.to_image` function is used to return an image as a bytes object. You can also use the `.to_image` graph object figure method.
189150

@@ -215,7 +176,45 @@ img_bytes = fig.to_image(format="png", width=600, height=350, scale=2)
215176
Image(img_bytes)
216177
```
217178

218-
### Summary
219-
In summary, to export high-quality static images from plotly.py, all you need to do is install orca, psutil, and requests and then use the `plotly.io.write_image` and `plotly.io.to_image` functions (or the `.write_image` and `.to_image` graph object figure methods).
179+
<!-- #region -->
180+
### Specify Image Export Engine
181+
If `kaleido` is installed, it will automatically be used to perform image export. If it is not installed, plotly.py will attempt to use orca instead. The `engine` argument to the `to_image` and `write_image` functions can be used to override this default behavior.
182+
183+
Here is an example of specifying that orca should be used:
184+
```python
185+
fig.to_image(format="png", engine="orca")
186+
```
187+
188+
And, here is an example of specifying that Kaleido should be used:
189+
```python
190+
fig.to_image(format="png", engine="kaleido")
191+
```
192+
193+
<!-- #endregion -->
220194

221-
If you want to know more about how the orca integration works, or if you need to troubleshoot an issue, please check out the [Orca Management](/python/orca-management/) section.
195+
<!-- #region -->
196+
### Image Export Settings (Kaleido)
197+
Various image export settings can be configured using the `plotly.io.kaleido.scope` object. For example, the `default_format` property can be used to specify that the default export format should be `svg` instead of `png`
198+
199+
```python
200+
import plotly.io as pio
201+
pio.kaleido.scope.default_format = "svg"
202+
```
203+
204+
Here is a complete listing of the available image export settings:
205+
206+
- **`default_width`**: The default pixel width to use on image export.
207+
- **`default_height`**: The default pixel height to use on image export.
208+
- **`default_scale`**: The default image scale factor applied on image export.
209+
- **`default_format`**: The default image format used on export. One of `"png"`, `"jpeg"`, `"webp"`, `"svg"`, `"pdf"`, or `"eps"`.
210+
- **`mathjax`**: Location of the MathJax bundle needed to render LaTeX characters. Defaults to a CDN location. If fully offline export is required, set this to a local MathJax bundle.
211+
- **`topojson`**: Location of the topojson files needed to render choropleth traces. Defaults to a CDN location. If fully offline export is required, set this to a local directory containing the [Plotly.js topojson files](https://github.com/plotly/plotly.js/tree/master/dist/topojson).
212+
- **`mapbox_access_token`**: The default Mapbox access token.
213+
214+
<!-- #endregion -->
215+
216+
### Image Export Settings (Orca)
217+
See the [Orca Management](/python/orca-management/) section for information on how to specify image export settings when using orca.
218+
219+
### Summary
220+
In summary, to export high-quality static images from plotly.py, all you need to do is install the `kaleido` package and then use the `plotly.io.write_image` and `plotly.io.to_image` functions (or the `.write_image` and `.to_image` graph object figure methods).

Diff for: packages/python/plotly/plotly/basedatatypes.py

+11
Original file line numberDiff line numberDiff line change
@@ -3172,6 +3172,12 @@ def to_image(self, *args, **kwargs):
31723172
True if the figure should be validated before being converted to
31733173
an image, False otherwise.
31743174
3175+
engine: str
3176+
Image export engine to use:
3177+
- "kaleido": Use Kaleido for image export
3178+
- "orca": Use Orca for image export
3179+
- "auto" (default): Use Kaleido if installed, otherwise use orca
3180+
31753181
Returns
31763182
-------
31773183
bytes
@@ -3231,6 +3237,11 @@ def write_image(self, *args, **kwargs):
32313237
True if the figure should be validated before being converted to
32323238
an image, False otherwise.
32333239
3240+
engine: str
3241+
Image export engine to use:
3242+
- "kaleido": Use Kaleido for image export
3243+
- "orca": Use Orca for image export
3244+
- "auto" (default): Use Kaleido if installed, otherwise use orca
32343245
Returns
32353246
-------
32363247
None

Diff for: packages/python/plotly/plotly/io/__init__.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
import sys
33

44
if sys.version_info < (3, 7):
5-
from ._orca import to_image, write_image
6-
from . import orca
5+
from ._kaleido import to_image, write_image
6+
from . import orca, kaleido
77
from ._json import to_json, from_json, read_json, write_json
88
from ._templates import templates, to_templated
99
from ._html import to_html, write_html
@@ -29,10 +29,10 @@
2929
else:
3030
__all__, __getattr__, __dir__ = relative_import(
3131
__name__,
32-
[".orca", ".base_renderers"],
32+
[".orca", ".kaleido", ".base_renderers"],
3333
[
34-
"._orca.to_image",
35-
"._orca.write_image",
34+
"._kaleido.to_image",
35+
"._kaleido.write_image",
3636
"._json.to_json",
3737
"._json.from_json",
3838
"._json.read_json",

0 commit comments

Comments
 (0)