1
1
import os
2
2
import json
3
3
from pathlib import Path
4
+ import importlib .metadata as importlib_metadata
5
+ from packaging .version import Version
6
+ import tempfile
7
+
4
8
import plotly
5
9
from plotly .io ._utils import validate_coerce_fig_to_dict
6
10
7
11
try :
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
21
33
PlotlyScope = None
22
34
scope = None
23
35
24
36
25
37
def 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
27
39
):
28
40
"""
29
41
Convert a figure to a static image bytes string
@@ -35,100 +47,52 @@ def to_image(
35
47
36
48
format: str or None
37
49
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)
44
56
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`
48
58
49
59
width: int or None
50
60
The width of the exported image in layout pixels. If the `scale`
51
61
property is 1.0, this will also be the width of the exported image
52
62
in physical pixels.
53
63
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`
57
65
58
66
height: int or None
59
67
The height of the exported image in layout pixels. If the `scale`
60
68
property is 1.0, this will also be the height of the exported image
61
69
in physical pixels.
62
70
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`
66
72
67
73
scale: int or float or None
68
74
The scale factor to use when exporting the figure. A scale factor
69
75
larger than 1.0 will increase the image resolution with respect
70
76
to the figure's layout pixel dimensions. Whereas as scale factor of
71
77
less than 1.0 will decrease the image resolution.
72
78
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`
77
80
78
81
validate: bool
79
82
True if the figure should be validated before being converted to
80
83
an image, False otherwise.
81
84
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.
87
87
88
88
Returns
89
89
-------
90
90
bytes
91
91
The image data
92
92
"""
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
- )
129
93
130
94
# Raise informative error message if Kaleido is not installed
131
- if scope is None :
95
+ if not kaleido_available :
132
96
raise ValueError (
133
97
"""
134
98
Image export using the "kaleido" engine requires the kaleido package,
@@ -137,12 +101,32 @@ def to_image(
137
101
"""
138
102
)
139
103
140
- # Validate figure
141
- # ---------------
104
+ # Convert figure to dict (and validate if requested)
142
105
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
+ )
146
130
147
131
return img_bytes
148
132
@@ -190,38 +174,29 @@ def write_image(
190
174
property is 1.0, this will also be the width of the exported image
191
175
in physical pixels.
192
176
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`
196
178
197
179
height: int or None
198
180
The height of the exported image in layout pixels. If the `scale`
199
181
property is 1.0, this will also be the height of the exported image
200
182
in physical pixels.
201
183
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`
205
185
206
186
scale: int or float or None
207
187
The scale factor to use when exporting the figure. A scale factor
208
188
larger than 1.0 will increase the image resolution with respect
209
189
to the figure's layout pixel dimensions. Whereas as scale factor of
210
190
less than 1.0 will decrease the image resolution.
211
191
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`
215
193
216
194
validate: bool
217
195
True if the figure should be validated before being converted to
218
196
an image, False otherwise.
219
197
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.
225
200
226
201
Returns
227
202
-------
@@ -323,7 +298,7 @@ def full_figure_for_development(fig, warn=True, as_dict=False):
323
298
"""
324
299
325
300
# Raise informative error message if Kaleido is not installed
326
- if scope is None :
301
+ if not kaleido_available :
327
302
raise ValueError (
328
303
"""
329
304
Full figure generation requires the kaleido package,
@@ -341,7 +316,24 @@ def full_figure_for_development(fig, warn=True, as_dict=False):
341
316
"To suppress this warning, set warn=False"
342
317
)
343
318
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
+
345
337
if as_dict :
346
338
return fig
347
339
else :
0 commit comments