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 Kaleido image export support #2613

Merged
merged 31 commits into from
Jul 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
1c18fe4
Add kaleido image export option behind the kaleido_export future flag
jonmmease Jul 3, 2020
7467329
Add CHANGELOG entry
jonmmease Jul 3, 2020
b546fcc
Add eps/emf formats
jonmmease Jul 7, 2020
7f65f5f
Replace future flag with engine kwarg
jonmmease Jul 7, 2020
556ef96
emf only available with kaleido
jonmmease Jul 7, 2020
ed71d6a
import kaleido submodule when plotly.io is imported
jonmmease Jul 8, 2020
da4cb83
Update Image renderers with engine parameter
jonmmease Jul 8, 2020
3e1cbd4
Added kaleido engine tests
jonmmease Jul 8, 2020
299165d
Merge remote-tracking branch 'origin/master' into kaleido
jonmmease Jul 8, 2020
411ffb4
Python 2.7 mock compatibility
jonmmease Jul 8, 2020
de44623
Python 2.7 mock compatibility
jonmmease Jul 8, 2020
c5f4e48
Update CHANGELOG.md
jonmmease Jul 8, 2020
4c5fe76
Add kaleido test that actually calls Kaleido and checks that the
jonmmease Jul 8, 2020
011ec72
Remove broken EMF format as option
jonmmease Jul 8, 2020
b5fc3db
Merge remote-tracking branch 'origin/master' into kaleido
jonmmease Jul 8, 2020
f8bff56
Remove broken EMF format as option
jonmmease Jul 8, 2020
827af91
Update image export documentation to recommend and describe Kaleido
jonmmease Jul 9, 2020
ef6e68d
Add engine docstring to figure image export methods
jonmmease Jul 9, 2020
fc7d856
Change kaleido conda channel to plotly since it most likely won't be …
jonmmease Jul 10, 2020
aee0e0d
Conda package renamed from kaleido -> python-kaleido
jonmmease Jul 12, 2020
32f6e7f
Merge remote-tracking branch 'origin/master' into kaleido
jonmmease Jul 13, 2020
00987c0
in README: indicate that Keleido is new and improved and orca is legacy
jonmmease Jul 14, 2020
a25f5b2
Add Kaleido note to orca-management section
jonmmease Jul 14, 2020
a033df0
JPEG typo
jonmmease Jul 14, 2020
d1fc9a8
Merge "Install Dependency" sections and better explain that Kaleido i…
jonmmease Jul 14, 2020
2bdcfe2
Replace Orca with plotly.py when discussing supported image export fo…
jonmmease Jul 14, 2020
70c11ac
varying type
jonmmease Jul 14, 2020
e350025
factor typo [ci skip]
jonmmease Jul 14, 2020
967b728
Update CHANGELOG.md
jonmmease Jul 14, 2020
81a0bc7
Update doc/python/static-image-export.md
jonmmease Jul 14, 2020
74c4274
Update doc/python/orca-management.md
jonmmease Jul 14, 2020
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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Added

- 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)).
- `px.NO_COLOR` constant to override wide-form color assignment in Plotly Express ([#2614](https://github.com/plotly/plotly.py/pull/2614))
- `facet_row_spacing` and `facet_col_spacing` added to Plotly Express cartesian 2d functions ([#2614](https://github.com/plotly/plotly.py/pull/2614))

Expand All @@ -28,7 +29,6 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- 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.
- `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!


### Fixed

- `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!
Expand Down
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,26 @@ jupyter labextension install @jupyter-widgets/jupyterlab-manager plotlywidget@4.

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

### Static Image Export
### Static Image Export with Kaleido

plotly.py supports static image export using the `to_image` and `write_image`
functions in the `plotly.io` package. This functionality requires the
installation of the plotly [orca](https://github.com/plotly/orca) command line utility and the
[`psutil`](https://github.com/giampaolo/psutil) Python package.
functions in the `plotly.io` module. This functionality requires the
[`kaleido`](https://github.com/plotly/Kaleido) package which can be installed
using pip...

```
$ pip install -U kaleido
```

or conda.
```
$ conda install -c plotly python-kaleido
```

### Static Image Export with Orca
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
by the legacy [orca](https://github.com/plotly/orca) command line utility and the
[`psutil`](https://github.com/giampaolo/psutil) Python package.

These dependencies can both be installed using conda:

Expand Down
66 changes: 61 additions & 5 deletions doc/python/orca-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,72 @@ jupyter:
---

### Overview
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.
This section covers the lower-level details of how plotly.py can use orca to perform static image generation.

### What is Orca?
> 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 .

Please refer to the [Static Image Export](/python/static-image-export/) section for general information on creating static images from plotly.py figures.

### What is orca?
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.

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.

### Installing orca
There are 3 general approaches to installing orca and its Python dependencies.

##### conda
Using the [conda](https://conda.io/docs/) package manager, you can install these dependencies in a single command:
```
$ conda install -c plotly plotly-orca==1.2.1 psutil requests
```

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

##### npm + pip
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`:

```
$ npm install -g [email protected] orca
$ pip install psutil requests
```

##### Standalone Binaries + pip
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`.

```
$ pip install psutil requests
```

<!-- #region -->
### Install orca on Google Colab
```
!pip install plotly>=4.7.1
!wget https://github.com/plotly/orca/releases/download/v1.2.1/orca-1.2.1-x86_64.AppImage -O /usr/local/bin/orca
!chmod +x /usr/local/bin/orca
!apt-get install xvfb libgtk2.0-0 libgconf-2-4
```

Once this is done you can use this code to make, show and export a figure:

```python
import plotly.graph_objects as go
fig = go.Figure( go.Scatter(x=[1,2,3], y=[1,3,2] ) )
fig.write_image("fig1.svg")
fig.write_image("fig1.png")
```

The files can then be downloaded with:

```python
from google.colab import files
files.download('fig1.svg')
files.download('fig1.png')
```
<!-- #endregion -->

### Create a Figure
Now let's create a simple scatter plot with 100 random points of variying color and size.
Now let's create a simple scatter plot with 100 random points of varying color and size.

```python
import plotly.graph_objects as go
Expand Down Expand Up @@ -198,7 +254,7 @@ In addition to the `executable` property, the `plotly.io.orca.config` object can
- **`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.
- **`default_width`**: The default pixel width to use on image export.
- **`default_height`**: The default pixel height to use on image export.
- **`default_scale`**: The default image scale facor applied on image export.
- **`default_scale`**: The default image scale factor applied on image export.
- **`default_format`**: The default image format used on export. One of `"png"`, `"jpeg"`, `"webp"`, `"svg"`, `"pdf"`, or `"eps"`.
- **`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.
- **`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).
Expand All @@ -207,4 +263,4 @@ In addition to the `executable` property, the `plotly.io.orca.config` object can

Copy link
Contributor

Choose a reason for hiding this comment

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

line 253 should be - **default_scale**: The default image scale factor applied on image export.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 8731ecfe3402002d1eac53e74e7d7ce821b2c821


### Saving Configuration Settings
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.
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.
103 changes: 51 additions & 52 deletions doc/python/static-image-export.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,39 +37,27 @@ jupyter:

### Interactive vs Static Export

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


<!-- #region -->
#### Install Dependencies
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.

##### conda
Using the [conda](https://conda.io/docs/) package manager, you can install these dependencies in a single command:
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...
```
$ conda install -c plotly plotly-orca==1.2.1 psutil requests
$ pip install -U kaleido
```

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

##### npm + pip
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`:

```
$ npm install -g [email protected] orca
$ pip install psutil requests
or conda.
```
$ conda install -c plotly python-kaleido
```

##### Standalone Binaries + pip
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`.
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.

```
$ pip install psutil requests
```
<!-- #endregion -->

### Create a Figure
Copy link
Contributor

Choose a reason for hiding this comment

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

line 61 should be "Now let's create a simple scatter plot with 100 random points of varying color and size."

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 70c11ac

Now let's create a simple scatter plot with 100 random points of variying color and size.
Now let's create a simple scatter plot with 100 random points of varying color and size.

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


Orca can output figures to several raster image formats including **PNG**, ...
plotly.py can output figures to several raster image formats including **PNG**, ...

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


Orca can also output figures in several vector formats including **SVG**, ...
plotly.py can also output figures in several vector formats including **SVG**, ...

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

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

<!-- #region -->
### Install orca on Google Colab
```
!pip install plotly>=4.7.1
!wget https://github.com/plotly/orca/releases/download/v1.2.1/orca-1.2.1-x86_64.AppImage -O /usr/local/bin/orca
!chmod +x /usr/local/bin/orca
!apt-get install xvfb libgtk2.0-0 libgconf-2-4
```

Once this is done you can use this code to make, show and export a figure:

```python
import plotly.graph_objects as go
fig = go.Figure( go.Scatter(x=[1,2,3], y=[1,3,2] ) )
fig.write_image("fig1.svg")
fig.write_image("fig1.png")
```

The files can then be downloaded with:

```python
from google.colab import files
files.download('fig1.svg')
files.download('fig1.png')
```
<!-- #endregion -->

### Get Image as Bytes
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.

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

### Summary
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).
<!-- #region -->
### Specify Image Export Engine
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.

Here is an example of specifying that orca should be used:
```python
fig.to_image(format="png", engine="orca")
```

And, here is an example of specifying that Kaleido should be used:
```python
fig.to_image(format="png", engine="kaleido")
```

<!-- #endregion -->

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.
<!-- #region -->
### Image Export Settings (Kaleido)
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`

```python
import plotly.io as pio
pio.kaleido.scope.default_format = "svg"
```

Here is a complete listing of the available image export settings:

- **`default_width`**: The default pixel width to use on image export.
- **`default_height`**: The default pixel height to use on image export.
- **`default_scale`**: The default image scale factor applied on image export.
- **`default_format`**: The default image format used on export. One of `"png"`, `"jpeg"`, `"webp"`, `"svg"`, `"pdf"`, or `"eps"`.
- **`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.
- **`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).
- **`mapbox_access_token`**: The default Mapbox access token.

<!-- #endregion -->

### Image Export Settings (Orca)
See the [Orca Management](/python/orca-management/) section for information on how to specify image export settings when using orca.

### Summary
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).
11 changes: 11 additions & 0 deletions packages/python/plotly/plotly/basedatatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3172,6 +3172,12 @@ def to_image(self, *args, **kwargs):
True if the figure should be validated before being converted to
an image, False otherwise.

engine: str
Image export engine to use:
- "kaleido": Use Kaleido for image export
- "orca": Use Orca for image export
- "auto" (default): Use Kaleido if installed, otherwise use orca

Returns
-------
bytes
Expand Down Expand Up @@ -3231,6 +3237,11 @@ def write_image(self, *args, **kwargs):
True if the figure should be validated before being converted to
an image, False otherwise.

engine: str
Image export engine to use:
- "kaleido": Use Kaleido for image export
- "orca": Use Orca for image export
- "auto" (default): Use Kaleido if installed, otherwise use orca
Returns
-------
None
Expand Down
10 changes: 5 additions & 5 deletions packages/python/plotly/plotly/io/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import sys

if sys.version_info < (3, 7):
from ._orca import to_image, write_image
from . import orca
from ._kaleido import to_image, write_image
from . import orca, kaleido
from ._json import to_json, from_json, read_json, write_json
from ._templates import templates, to_templated
from ._html import to_html, write_html
Expand All @@ -29,10 +29,10 @@
else:
__all__, __getattr__, __dir__ = relative_import(
__name__,
[".orca", ".base_renderers"],
[".orca", ".kaleido", ".base_renderers"],
[
"._orca.to_image",
"._orca.write_image",
"._kaleido.to_image",
"._kaleido.write_image",
"._json.to_json",
"._json.from_json",
"._json.read_json",
Expand Down
Loading