-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Use plotly.js base64
API to store and pass typed arrays declared by numpy, pandas, etc.
#4470
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
Changes from 121 commits
1f3e605
a627c9e
c363f3e
61aa4ea
730c0dd
7c31dc1
d4c3162
d1b4706
2b33199
f2c8d66
b4d23b5
03aa9e0
4514e92
048455e
520e9bf
c48f3ce
dcb6b91
9b1cbfd
bd7e9dc
124f12d
82c8199
f200767
5fb9ee3
b31dc27
0323215
99ebbbc
7c7ef30
f5df6db
f332922
5947221
62d9aa7
e5c24fe
8430c52
baeedc9
4f63296
a566543
3d63fa2
7fbb701
6e53e51
dd1aba8
b6f9d14
555d960
b301d99
4323c28
c1e6728
7822635
58d4844
43de1cb
1105328
65f0dad
da100bc
554f5cb
024f3c1
8a051a3
ece3e3d
0675f5b
2fc29f8
d8924c5
e1f91cd
98f2541
3702686
4932cdb
ddbc3f1
0b83ebd
dabbcb8
6c01e6a
a056d7e
6d82e48
8823a8c
25f6ccf
b931fd5
addfd47
ef51cce
3142c62
72e9ad0
2d4ad05
9d3b50d
63335d2
644992f
0f68aff
2a81d2a
1c0b48e
e500e38
c2453d3
c8d35b4
8861451
8afa4d8
69729db
c52e9f4
c6390f4
a3940ee
259d509
d201b58
f018291
8d7edf6
d59ceb0
40166bb
17b531c
2fa09e5
4452868
02fb3a4
a8995b7
12ff7f3
ca4340b
dd9379a
9362db3
6364d4e
61e9178
066564e
fb036c7
4b289e9
aabfa6e
de2bcb5
0d0dad2
9c5d112
5e50d8c
8fff9c5
bd0a2d3
b3ed838
7bd7993
cd8e0be
f60b122
9d6b0c7
960adb9
12ab42a
59fe206
60c73a8
f481af7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -81,7 +81,7 @@ commands: | |
pytest plotly/tests/test_io | ||
no_output_timeout: 20m | ||
- run: | ||
name: Test dependencdies not imported | ||
name: Test dependencies not imported | ||
command: | | ||
cd packages/python/plotly | ||
. venv/bin/activate | ||
|
@@ -92,46 +92,6 @@ commands: | |
cd packages/python/plotly | ||
. venv/bin/activate | ||
pytest -x test_init/test_lazy_imports.py | ||
test_orca: | ||
parameters: | ||
py: | ||
default: "310" | ||
type: string | ||
steps: | ||
- checkout | ||
- browser-tools/install-chrome | ||
- browser-tools/install-chromedriver | ||
- run: | ||
name: Install dependencies | ||
command: | | ||
cd packages/python/plotly | ||
python -m venv venv | ||
. venv/bin/activate | ||
pip install --upgrade pip wheel | ||
pip install -r ./test_requirements/requirements_<<parameters.py>>_optional.txt | ||
- run: | ||
name: Install plotly-geo | ||
command: | | ||
cd packages/python/plotly-geo | ||
. ../plotly/venv/bin/activate | ||
pip install -e . | ||
- run: | ||
name: Install orca | ||
command: | | ||
npm install [email protected] | ||
npm install orca | ||
sudo apt-get update | ||
sudo apt-get install -y poppler-utils libxtst6 xvfb libgtk2.0-0 libgconf-2-4 libnss3 libasound2 rename | ||
echo 'export PATH="/home/circleci/project/node_modules/.bin:$PATH"' >> $BASH_ENV | ||
- run: | ||
name: Test orca | ||
command: | | ||
cd packages/python/plotly | ||
. venv/bin/activate | ||
pytest plotly/tests/test_orca | ||
no_output_timeout: 20m | ||
- store_artifacts: | ||
path: packages/python/plotly/plotly/tests/test_orca/images/linux/failed | ||
|
||
jobs: | ||
check-code-formatting: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,116 @@ | ||
import base64 | ||
import decimal | ||
import json as _json | ||
import sys | ||
import re | ||
from functools import reduce | ||
|
||
from _plotly_utils.optional_imports import get_module | ||
from _plotly_utils.basevalidators import ImageUriValidator | ||
from _plotly_utils.basevalidators import ( | ||
ImageUriValidator, | ||
copy_to_readonly_numpy_array, | ||
is_homogeneous_array, | ||
) | ||
|
||
|
||
int8min = -128 | ||
int8max = 127 | ||
int16min = -32768 | ||
int16max = 32767 | ||
int32min = -2147483648 | ||
int32max = 2147483647 | ||
|
||
uint8max = 255 | ||
uint16max = 65535 | ||
uint32max = 4294967295 | ||
|
||
plotlyjsShortTypes = { | ||
"int8": "i1", | ||
"uint8": "u1", | ||
"int16": "i2", | ||
"uint16": "u2", | ||
"int32": "i4", | ||
"uint32": "u4", | ||
"float32": "f4", | ||
"float64": "f8", | ||
} | ||
|
||
|
||
def to_typed_array_spec(v): | ||
""" | ||
Convert numpy array to plotly.js typed array spec | ||
If not possible return the original value | ||
""" | ||
v = copy_to_readonly_numpy_array(v) | ||
|
||
np = get_module("numpy", should_load=False) | ||
if not isinstance(v, np.ndarray): | ||
return v | ||
|
||
dtype = str(v.dtype) | ||
|
||
# convert default Big Ints until we could support them in plotly.js | ||
if dtype == "int64": | ||
max = v.max() | ||
min = v.min() | ||
if max <= int8max and min >= int8min: | ||
v = v.astype("int8") | ||
elif max <= int16max and min >= int16min: | ||
v = v.astype("int16") | ||
elif max <= int32max and min >= int32min: | ||
v = v.astype("int32") | ||
else: | ||
return v | ||
|
||
elif dtype == "uint64": | ||
max = v.max() | ||
min = v.min() | ||
if max <= uint8max and min >= 0: | ||
v = v.astype("uint8") | ||
elif max <= uint16max and min >= 0: | ||
v = v.astype("uint16") | ||
elif max <= uint32max and min >= 0: | ||
v = v.astype("uint32") | ||
else: | ||
return v | ||
|
||
dtype = str(v.dtype) | ||
|
||
if dtype in plotlyjsShortTypes: | ||
arrObj = { | ||
"dtype": plotlyjsShortTypes[dtype], | ||
"bdata": base64.b64encode(v).decode("ascii"), | ||
} | ||
|
||
if v.ndim > 1: | ||
arrObj["shape"] = str(v.shape)[1:-1] | ||
|
||
return arrObj | ||
|
||
return v | ||
|
||
|
||
def is_skipped_key(key): | ||
""" | ||
Return whether any keys in the parent hierarchy are in the list of keys that | ||
are skipped for conversion to the typed array spec | ||
""" | ||
skipped_keys = ["geojson", "layer", "range"] | ||
return any(skipped_key in key for skipped_key in skipped_keys) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @marthacryan Shouldn't the test be Or we really do want to be checking that the skipped key is a substring of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also I think the docstring comment is no longer accurate |
||
|
||
|
||
def convert_to_base64(obj): | ||
if isinstance(obj, dict): | ||
for key, value in obj.items(): | ||
if is_skipped_key(key): | ||
continue | ||
elif is_homogeneous_array(value): | ||
obj[key] = to_typed_array_spec(value) | ||
else: | ||
convert_to_base64(value) | ||
elif isinstance(obj, list) or isinstance(obj, tuple): | ||
for value in obj: | ||
convert_to_base64(value) | ||
|
||
|
||
def cumsum(x): | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ def validate_coerce_fig_to_dict(fig, validate): | |
typ=type(fig), v=fig | ||
) | ||
) | ||
|
||
return fig_dict | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't this line raise an error if
numpy
is not installed? (Sinceget_module
will returnNone
in that case.)Is that ok?