Skip to content

Commit 6293f94

Browse files
authored
Merge branch 'master' into merge-doc-prod-to-master
2 parents dbf9d87 + 31b042d commit 6293f94

File tree

19 files changed

+263
-185
lines changed

19 files changed

+263
-185
lines changed

Diff for: .circleci/config.yml

-9
Original file line numberDiff line numberDiff line change
@@ -249,14 +249,6 @@ jobs:
249249
- test_optional:
250250
py: "312_no_numpy"
251251

252-
# Orca
253-
python_38_orca:
254-
docker:
255-
- image: cimg/python:3.8-browsers
256-
steps:
257-
- test_orca:
258-
py: "38"
259-
260252
# Percy
261253
python_39_percy:
262254
docker:
@@ -613,7 +605,6 @@ workflows:
613605
- python_311_optional
614606
- python_312_optional
615607
- python_39_pandas_2_optional
616-
- python_38_orca
617608
- python_39_percy
618609
- python_312_no_numpy
619610
- build-doc

Diff for: CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
All notable changes to this project will be documented in this file.
33
This project adheres to [Semantic Versioning](http://semver.org/).
44

5+
### Updated
6+
7+
- Updated plotly.py to use base64 encoding of arrays in plotly JSON to improve performance.
8+
59
## [5.24.1] - 2024-09-12
610

711
### Updated
@@ -21,6 +25,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
2125

2226
- Fixed a bug in integer validation of arrays that threw an error when an array contained a mix of strings and integers.
2327

28+
- Fixed a bug in JupyterLab >= 4 and Jupyter Notebook >= 7 that caused latex to not render in plotly charts.
29+
30+
- Use modern [native ES6 import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) to load plotly.js bundle instead of requirejs which is [no longer under active development](https://github.com/requirejs/r.js/compare/2.3.6...2.3.7)
31+
2432
## [5.23.0] - 2024-07-23
2533

2634
### Updated

Diff for: LICENSE.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
The MIT License (MIT)
1+
MIT License
22

3-
Copyright (c) 2016-2018 Plotly, Inc
3+
Copyright (c) 2016-2024 Plotly Technologies Inc.
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

Diff for: contributing.md

+3-5
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,7 @@ There are many ways to contribute to plotly.py. To contribute effectively, it is
5757

5858
- tests are found in `packages/python/plotly/plotly/tests`. Different
5959
directories correspond to different test jobs (with different dependency sets)
60-
run in continuous integration. These jobs are configured in
61-
`packages/python/plotly/tox.ini`, which itself is used in the Circle CI
62-
configuration file `.circleci/config.yml`. More is explained about tests
60+
run in continuous integration. More is explained about tests
6361
in the following "Technical aspects" section.
6462

6563
- the **documentation** is part of this repository. Its structure and some
@@ -231,10 +229,10 @@ For dev branches, it is also possible to use `updateplotlyjsdev` in two configur
231229

232230
### CircleCI Release
233231

234-
If your devbranch is part of the official plotly.js repository, you can use
232+
If your devbranch is part of the official plotly.js repository, you can use
235233
```bash
236234
python setup.py updateplotlyjsdev --devrepo reponame --devbranch branchname
237-
```
235+
```
238236
to update to development versions of `plotly.js`. This will fetch the `plotly.js` in the CircleCI artifact of the branch `branchname` of the repo `reponame`. If `--devrepo` or `--devbranch` are omitted, `updateplotlyjsdev` defaults using `plotly/plotly.js` and `master` respectively.
239237

240238
### Local Repository

Diff for: doc/python/renderers.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ The `plotly_mimetype` renderer creates a specification of the figure (called a M
164164
These are aliases for `plotly_mimetype` since this renderer is a good choice when working in JupyterLab, nteract, and the Visual Studio Code notebook interface. Note that in VSCode Notebooks, the version of Plotly.js that is used to render is provided by the [vscode-python extension](https://code.visualstudio.com/docs/languages/python) and often trails the latest version by several weeks, so the latest features of `plotly` may not be available in VSCode right away. The situation is similar for Nteract.
165165

166166
##### Static Image Renderers
167-
A set of renderers is provided for displaying figures as static images. These renderers all rely on the [orca](https://github.com/plotly/orca) static image export utility. See the [Static Image Export](https://plot.ly/python/static-image-export/) page for more information on getting set up with [orca].
167+
A set of renderers is provided for displaying figures as static images. See the [Static Image Export](https://plot.ly/python/static-image-export/) page for more information on getting set up.
168168

169169
###### `png`, `jpeg`, and `svg`
170170
These renderers display figures as static `.png`, `.jpeg`, and `.svg` files, respectively. These renderers are useful for user interfaces that do not support inline HTML output, but do support inline static images. Examples include the [QtConsole](https://qtconsole.readthedocs.io/en/stable/), [Spyder](https://www.spyder-ide.org/), and the PyCharm [notebook interface](https://www.jetbrains.com/help/pycharm/jupyter-notebook-support.html).

Diff for: doc/requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
plotly==5.24.1
2-
jupytext==1.1.1
2+
jupytext==1.16.4
33
ipywidgets==7.7.2
44
jupyter-client<7
55
jupyter

Diff for: packages/python/chart-studio/chart_studio/tools.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ def _get_embed_url(file_owner_or_url, file_id=None):
287287
"The 'file_id' argument must be a non-negative number."
288288
)
289289

290-
if share_key is "":
290+
if share_key == "":
291291
return "{plotly_rest_url}/~{file_owner}/{file_id}.embed".format(
292292
plotly_rest_url=plotly_rest_url, file_owner=file_owner, file_id=file_id
293293
)

Diff for: packages/python/plotly/_plotly_utils/utils.py

+105-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,115 @@
1+
import base64
12
import decimal
23
import json as _json
34
import sys
45
import re
56
from functools import reduce
67

78
from _plotly_utils.optional_imports import get_module
8-
from _plotly_utils.basevalidators import ImageUriValidator
9+
from _plotly_utils.basevalidators import (
10+
ImageUriValidator,
11+
copy_to_readonly_numpy_array,
12+
is_homogeneous_array,
13+
)
14+
15+
16+
int8min = -128
17+
int8max = 127
18+
int16min = -32768
19+
int16max = 32767
20+
int32min = -2147483648
21+
int32max = 2147483647
22+
23+
uint8max = 255
24+
uint16max = 65535
25+
uint32max = 4294967295
26+
27+
plotlyjsShortTypes = {
28+
"int8": "i1",
29+
"uint8": "u1",
30+
"int16": "i2",
31+
"uint16": "u2",
32+
"int32": "i4",
33+
"uint32": "u4",
34+
"float32": "f4",
35+
"float64": "f8",
36+
}
37+
38+
39+
def to_typed_array_spec(v):
40+
"""
41+
Convert numpy array to plotly.js typed array spec
42+
If not possible return the original value
43+
"""
44+
v = copy_to_readonly_numpy_array(v)
45+
46+
np = get_module("numpy", should_load=False)
47+
if not np or not isinstance(v, np.ndarray):
48+
return v
49+
50+
dtype = str(v.dtype)
51+
52+
# convert default Big Ints until we could support them in plotly.js
53+
if dtype == "int64":
54+
max = v.max()
55+
min = v.min()
56+
if max <= int8max and min >= int8min:
57+
v = v.astype("int8")
58+
elif max <= int16max and min >= int16min:
59+
v = v.astype("int16")
60+
elif max <= int32max and min >= int32min:
61+
v = v.astype("int32")
62+
else:
63+
return v
64+
65+
elif dtype == "uint64":
66+
max = v.max()
67+
min = v.min()
68+
if max <= uint8max and min >= 0:
69+
v = v.astype("uint8")
70+
elif max <= uint16max and min >= 0:
71+
v = v.astype("uint16")
72+
elif max <= uint32max and min >= 0:
73+
v = v.astype("uint32")
74+
else:
75+
return v
76+
77+
dtype = str(v.dtype)
78+
79+
if dtype in plotlyjsShortTypes:
80+
arrObj = {
81+
"dtype": plotlyjsShortTypes[dtype],
82+
"bdata": base64.b64encode(v).decode("ascii"),
83+
}
84+
85+
if v.ndim > 1:
86+
arrObj["shape"] = str(v.shape)[1:-1]
87+
88+
return arrObj
89+
90+
return v
91+
92+
93+
def is_skipped_key(key):
94+
"""
95+
Return whether the key is skipped for conversion to the typed array spec
96+
"""
97+
skipped_keys = ["geojson", "layer", "layers", "range"]
98+
return any(skipped_key == key for skipped_key in skipped_keys)
99+
100+
101+
def convert_to_base64(obj):
102+
if isinstance(obj, dict):
103+
for key, value in obj.items():
104+
if is_skipped_key(key):
105+
continue
106+
elif is_homogeneous_array(value):
107+
obj[key] = to_typed_array_spec(value)
108+
else:
109+
convert_to_base64(value)
110+
elif isinstance(obj, list) or isinstance(obj, tuple):
111+
for value in obj:
112+
convert_to_base64(value)
9113

10114

11115
def cumsum(x):

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

+4-12
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
display_string_positions,
1616
chomp_empty_strings,
1717
find_closest_string,
18+
convert_to_base64,
1819
)
1920
from _plotly_utils.exceptions import PlotlyKeyError
2021
from .optional_imports import get_module
@@ -3310,6 +3311,9 @@ def to_dict(self):
33103311
if frames:
33113312
res["frames"] = frames
33123313

3314+
# Add base64 conversion before sending to the front-end
3315+
convert_to_base64(res)
3316+
33133317
return res
33143318

33153319
def to_plotly_json(self):
@@ -3534,12 +3538,6 @@ def to_html(self, *args, **kwargs):
35343538
plotly.min.js bundle that is assumed to reside in the same
35353539
directory as the HTML file.
35363540
3537-
If 'require', Plotly.js is loaded using require.js. This option
3538-
assumes that require.js is globally available and that it has been
3539-
globally configured to know how to find Plotly.js as 'plotly'.
3540-
This option is not advised when full_html=True as it will result
3541-
in a non-functional html file.
3542-
35433541
If a string that ends in '.js', a script tag is included that
35443542
references the specified path. This approach can be used to point
35453543
the resulting HTML file to an alternative CDN or local bundle.
@@ -3643,12 +3641,6 @@ def write_html(self, *args, **kwargs):
36433641
directory because the plotly.js source code will be included only
36443642
once per output directory, rather than once per output file.
36453643
3646-
If 'require', Plotly.js is loaded using require.js. This option
3647-
assumes that require.js is globally available and that it has been
3648-
globally configured to know how to find Plotly.js as 'plotly'.
3649-
This option is not advised when full_html=True as it will result
3650-
in a non-functional html file.
3651-
36523644
If a string that ends in '.js', a script tag is included that
36533645
references the specified path. This approach can be used to point
36543646
the resulting HTML file to an alternative CDN or local bundle.

Diff for: packages/python/plotly/plotly/express/_chart_types.py

+11-11
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ def line(
258258
height=None,
259259
) -> go.Figure:
260260
"""
261-
In a 2D line plot, each row of `data_frame` is represented as vertex of
261+
In a 2D line plot, each row of `data_frame` is represented as a vertex of
262262
a polyline mark in 2D space.
263263
"""
264264
return make_figure(args=locals(), constructor=go.Scatter)
@@ -309,8 +309,8 @@ def area(
309309
) -> go.Figure:
310310
"""
311311
In a stacked area plot, each row of `data_frame` is represented as
312-
vertex of a polyline mark in 2D space. The area between successive
313-
polylines is filled.
312+
a vertex of a polyline mark in 2D space. The area between
313+
successive polylines is filled.
314314
"""
315315
return make_figure(
316316
args=locals(),
@@ -821,7 +821,7 @@ def line_3d(
821821
height=None,
822822
) -> go.Figure:
823823
"""
824-
In a 3D line plot, each row of `data_frame` is represented as vertex of
824+
In a 3D line plot, each row of `data_frame` is represented as a vertex of
825825
a polyline mark in 3D space.
826826
"""
827827
return make_figure(args=locals(), constructor=go.Scatter3d)
@@ -902,7 +902,7 @@ def line_ternary(
902902
) -> go.Figure:
903903
"""
904904
In a ternary line plot, each row of `data_frame` is represented as
905-
vertex of a polyline mark in ternary coordinates.
905+
a vertex of a polyline mark in ternary coordinates.
906906
"""
907907
return make_figure(args=locals(), constructor=go.Scatterternary)
908908

@@ -992,8 +992,8 @@ def line_polar(
992992
height=None,
993993
) -> go.Figure:
994994
"""
995-
In a polar line plot, each row of `data_frame` is represented as vertex
996-
of a polyline mark in polar coordinates.
995+
In a polar line plot, each row of `data_frame` is represented as a
996+
vertex of a polyline mark in polar coordinates.
997997
"""
998998
return make_figure(args=locals(), constructor=go.Scatterpolar)
999999

@@ -1199,7 +1199,7 @@ def line_geo(
11991199
) -> go.Figure:
12001200
"""
12011201
In a geographic line plot, each row of `data_frame` is represented as
1202-
vertex of a polyline mark on a map.
1202+
a vertex of a polyline mark on a map.
12031203
"""
12041204
return make_figure(
12051205
args=locals(),
@@ -1314,7 +1314,7 @@ def density_map(
13141314
) -> go.Figure:
13151315
"""
13161316
In a density map, each row of `data_frame` contributes to the intensity of
1317-
the color of the region around the corresponding point on the map
1317+
the color of the region around the corresponding point on the map.
13181318
"""
13191319
return make_figure(
13201320
args=locals(), constructor=go.Densitymap, trace_patch=dict(radius=radius)
@@ -1350,7 +1350,7 @@ def line_map(
13501350
) -> go.Figure:
13511351
"""
13521352
In a line map, each row of `data_frame` is represented as
1353-
vertex of a polyline mark on the map.
1353+
a vertex of a polyline mark on the map.
13541354
"""
13551355
return make_figure(args=locals(), constructor=go.Scattermap)
13561356

@@ -1497,7 +1497,7 @@ def line_mapbox(
14971497
) -> go.Figure:
14981498
"""
14991499
In a Mapbox line plot, each row of `data_frame` is represented as
1500-
vertex of a polyline mark on a Mapbox map.
1500+
a vertex of a polyline mark on a Mapbox map.
15011501
"""
15021502
return make_figure(args=locals(), constructor=go.Scattermapbox)
15031503

Diff for: packages/python/plotly/plotly/express/_core.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,7 @@ def process_args_into_dataframe(args, wide_mode, var_name, value_name):
12361236
raise ValueError(
12371237
"All arguments should have the same length. "
12381238
"The length of column argument `df[%s]` is %d, whereas the "
1239-
"length of previously-processed arguments %s is %d"
1239+
"length of previously-processed arguments %s is %d"
12401240
% (
12411241
field,
12421242
len(df_input[argument]),
@@ -1274,7 +1274,7 @@ def process_args_into_dataframe(args, wide_mode, var_name, value_name):
12741274
raise ValueError(
12751275
"All arguments should have the same length. "
12761276
"The length of argument `%s` is %d, whereas the "
1277-
"length of previously-processed arguments %s is %d"
1277+
"length of previously-processed arguments %s is %d"
12781278
% (field, len(argument), str(list(df_output.keys())), length)
12791279
)
12801280
df_output[str(col_name)] = to_unindexed_series(argument, str(col_name))

0 commit comments

Comments
 (0)