11import os
22import json
33from pathlib import Path
4+ import importlib .metadata as importlib_metadata
5+ from packaging .version import Version
6+ import tempfile
7+
48import plotly
59from plotly .io ._utils import validate_coerce_fig_to_dict
610
711try :
8- from kaleido .scopes .plotly import PlotlyScope
9-
10- scope = PlotlyScope ()
11-
12- # Compute absolute path to the 'plotly/package_data/' directory
13- root_dir = os .path .dirname (os .path .abspath (plotly .__file__ ))
14- package_dir = os .path .join (root_dir , "package_data" )
15- scope .plotlyjs = os .path .join (package_dir , "plotly.min.js" )
16- if scope .mathjax is None :
17- scope .mathjax = (
18- "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js"
19- )
20- except ImportError :
12+ import kaleido
13+
14+ kaleido_available = True
15+ kaleido_major = Version (importlib_metadata .version ("kaleido" )).major
16+
17+ if kaleido_major < 1 :
18+ # Kaleido v0
19+ from kaleido .scopes .plotly import PlotlyScope
20+
21+ scope = PlotlyScope ()
22+ # Compute absolute path to the 'plotly/package_data/' directory
23+ root_dir = os .path .dirname (os .path .abspath (plotly .__file__ ))
24+ package_dir = os .path .join (root_dir , "package_data" )
25+ scope .plotlyjs = os .path .join (package_dir , "plotly.min.js" )
26+ if scope .mathjax is None :
27+ scope .mathjax = (
28+ "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js"
29+ )
30+ except ImportError as e :
31+ kaleido_available = False
32+ kaleido_major = - 1
2133 PlotlyScope = None
2234 scope = None
2335
2436
2537def to_image (
26- fig , format = None , width = None , height = None , scale = None , validate = True , engine = "auto"
38+ fig , format = None , width = None , height = None , scale = None , validate = True , engine = None
2739):
2840 """
2941 Convert a figure to a static image bytes string
@@ -35,100 +47,52 @@ def to_image(
3547
3648 format: str or None
3749 The desired image format. One of
38- - 'png'
39- - 'jpg' or 'jpeg'
40- - 'webp'
41- - 'svg'
42- - 'pdf'
43- - 'eps' (Requires the poppler library to be installed and on the PATH)
50+ - 'png'
51+ - 'jpg' or 'jpeg'
52+ - 'webp'
53+ - 'svg'
54+ - 'pdf'
55+ - 'eps' (Requires the poppler library to be installed and on the PATH)
4456
45- If not specified, will default to:
46- - `plotly.io.kaleido.scope.default_format` if engine is "kaleido"
47- - `plotly.io.orca.config.default_format` if engine is "orca"
57+ If not specified, will default to `plotly.io.kaleido.scope.default_format`
4858
4959 width: int or None
5060 The width of the exported image in layout pixels. If the `scale`
5161 property is 1.0, this will also be the width of the exported image
5262 in physical pixels.
5363
54- If not specified, will default to:
55- - `plotly.io.kaleido.scope.default_width` if engine is "kaleido"
56- - `plotly.io.orca.config.default_width` if engine is "orca"
64+ If not specified, will default to `plotly.io.kaleido.scope.default_width`
5765
5866 height: int or None
5967 The height of the exported image in layout pixels. If the `scale`
6068 property is 1.0, this will also be the height of the exported image
6169 in physical pixels.
6270
63- If not specified, will default to:
64- - `plotly.io.kaleido.scope.default_height` if engine is "kaleido"
65- - `plotly.io.orca.config.default_height` if engine is "orca"
71+ If not specified, will default to `plotly.io.kaleido.scope.default_height`
6672
6773 scale: int or float or None
6874 The scale factor to use when exporting the figure. A scale factor
6975 larger than 1.0 will increase the image resolution with respect
7076 to the figure's layout pixel dimensions. Whereas as scale factor of
7177 less than 1.0 will decrease the image resolution.
7278
73- If not specified, will default to:
74- - `plotly.io.kaleido.scope.default_scale` if engine is "kaleido"
75- - `plotly.io.orca.config.default_scale` if engine is "orca"
76-
79+ If not specified, will default to `plotly.io.kaleido.scope.default_scale`
7780
7881 validate: bool
7982 True if the figure should be validated before being converted to
8083 an image, False otherwise.
8184
82- engine: str
83- Image export engine to use:
84- - "kaleido": Use Kaleido for image export
85- - "orca": Use Orca for image export
86- - "auto" (default): Use Kaleido if installed, otherwise use orca
85+ engine (deprecated): str
86+ No longer used. Kaleido is the only supported engine.
8787
8888 Returns
8989 -------
9090 bytes
9191 The image data
9292 """
93- # Handle engine
94- # -------------
95- if engine == "auto" :
96- if scope is not None :
97- # Default to kaleido if available
98- engine = "kaleido"
99- else :
100- # See if orca is available
101- from ._orca import validate_executable
102-
103- try :
104- validate_executable ()
105- engine = "orca"
106- except :
107- # If orca not configured properly, make sure we display the error
108- # message advising the installation of kaleido
109- engine = "kaleido"
110-
111- if engine == "orca" :
112- # Fall back to legacy orca image export path
113- from ._orca import to_image as to_image_orca
114-
115- return to_image_orca (
116- fig ,
117- format = format ,
118- width = width ,
119- height = height ,
120- scale = scale ,
121- validate = validate ,
122- )
123- elif engine != "kaleido" :
124- raise ValueError (
125- "Invalid image export engine specified: {engine}" .format (
126- engine = repr (engine )
127- )
128- )
12993
13094 # Raise informative error message if Kaleido is not installed
131- if scope is None :
95+ if not kaleido_available :
13296 raise ValueError (
13397 """
13498Image export using the "kaleido" engine requires the kaleido package,
@@ -137,12 +101,32 @@ def to_image(
137101"""
138102 )
139103
140- # Validate figure
141- # ---------------
104+ # Convert figure to dict (and validate if requested)
142105 fig_dict = validate_coerce_fig_to_dict (fig , validate )
143- img_bytes = scope .transform (
144- fig_dict , format = format , width = width , height = height , scale = scale
145- )
106+
107+ # Request image bytes
108+ if kaleido_major > 0 :
109+ # Kaleido v1
110+ opts = {
111+ k : v
112+ for k , v in dict (
113+ format = format ,
114+ width = width ,
115+ height = height ,
116+ scale = scale ,
117+ ).items ()
118+ if v is not None
119+ }
120+ img_bytes = kaleido .calc_fig_sync (
121+ fig_dict ,
122+ path = None ,
123+ opts = opts ,
124+ )
125+ else :
126+ # Kaleido v0
127+ img_bytes = scope .transform (
128+ fig_dict , format = format , width = width , height = height , scale = scale
129+ )
146130
147131 return img_bytes
148132
@@ -190,38 +174,29 @@ def write_image(
190174 property is 1.0, this will also be the width of the exported image
191175 in physical pixels.
192176
193- If not specified, will default to:
194- - `plotly.io.kaleido.scope.default_width` if engine is "kaleido"
195- - `plotly.io.orca.config.default_width` if engine is "orca"
177+ If not specified, will default to`plotly.io.kaleido.scope.default_width`
196178
197179 height: int or None
198180 The height of the exported image in layout pixels. If the `scale`
199181 property is 1.0, this will also be the height of the exported image
200182 in physical pixels.
201183
202- If not specified, will default to:
203- - `plotly.io.kaleido.scope.default_height` if engine is "kaleido"
204- - `plotly.io.orca.config.default_height` if engine is "orca"
184+ If not specified, will default to `plotly.io.kaleido.scope.default_height`
205185
206186 scale: int or float or None
207187 The scale factor to use when exporting the figure. A scale factor
208188 larger than 1.0 will increase the image resolution with respect
209189 to the figure's layout pixel dimensions. Whereas as scale factor of
210190 less than 1.0 will decrease the image resolution.
211191
212- If not specified, will default to:
213- - `plotly.io.kaleido.scope.default_scale` if engine is "kaleido"
214- - `plotly.io.orca.config.default_scale` if engine is "orca"
192+ If not specified, will default to `plotly.io.kaleido.scope.default_scale`
215193
216194 validate: bool
217195 True if the figure should be validated before being converted to
218196 an image, False otherwise.
219197
220- engine: str
221- Image export engine to use:
222- - "kaleido": Use Kaleido for image export
223- - "orca": Use Orca for image export
224- - "auto" (default): Use Kaleido if installed, otherwise use orca
198+ engine (deprecated): str
199+ No longer used. Kaleido is the only supported engine.
225200
226201 Returns
227202 -------
@@ -323,7 +298,7 @@ def full_figure_for_development(fig, warn=True, as_dict=False):
323298 """
324299
325300 # Raise informative error message if Kaleido is not installed
326- if scope is None :
301+ if not kaleido_available :
327302 raise ValueError (
328303 """
329304Full figure generation requires the kaleido package,
@@ -341,7 +316,24 @@ def full_figure_for_development(fig, warn=True, as_dict=False):
341316 "To suppress this warning, set warn=False"
342317 )
343318
344- fig = json .loads (scope .transform (fig , format = "json" ).decode ("utf-8" ))
319+ if kaleido_major > 0 :
320+ # Kaleido v1
321+ try :
322+ json_file = Path (tempfile .mkstemp (suffix = ".json" )[1 ])
323+ kaleido .write_fig_sync (
324+ fig ,
325+ json_file ,
326+ dict (format = "json" ),
327+ )
328+ with open (json_file , "r" ) as f :
329+ fig = json .load (f )
330+ finally :
331+ # Cleanup: remove temp file
332+ json_file .unlink ()
333+ else :
334+ # Kaleido v0
335+ fig = json .loads (scope .transform (fig , format = "json" ).decode ("utf-8" ))
336+
345337 if as_dict :
346338 return fig
347339 else :
0 commit comments