@@ -50,6 +50,83 @@ def to_scalar_or_list(v):
5050 return v
5151
5252
53+ plotlyjsShortTypes = {
54+ "int8" : "i1" ,
55+ "uint8" : "u1" ,
56+ "int16" : "i2" ,
57+ "uint16" : "u2" ,
58+ "int32" : "i4" ,
59+ "uint32" : "u4" ,
60+ "float32" : "f4" ,
61+ "float64" : "f8" ,
62+ }
63+
64+ int8min = - 128
65+ int8max = 127
66+ int16min = - 32768
67+ int16max = 32767
68+ int32min = - 2147483648
69+ int32max = 2147483647
70+
71+ uint8max = 255
72+ uint16max = 65535
73+ uint32max = 4294967295
74+
75+
76+ def to_typed_array_spec (v ):
77+ """
78+ Convert numpy array to plotly.js typed array sepc
79+ If not possible return the original value
80+ """
81+ v = copy_to_readonly_numpy_array (v )
82+
83+ np = get_module ("numpy" , should_load = False )
84+ if not isinstance (v , np .ndarray ):
85+ return v
86+
87+ dtype = str (v .dtype )
88+
89+ # convert default Big Ints until we could support them in plotly.js
90+ if dtype == "int64" :
91+ max = v .max ()
92+ min = v .min ()
93+ if max <= int8max and min >= int8min :
94+ v = v .astype ("int8" )
95+ elif max <= int16max and min >= int16min :
96+ v = v .astype ("int16" )
97+ elif max <= int32max and min >= int32min :
98+ v = v .astype ("int32" )
99+ else :
100+ return v
101+
102+ elif dtype == "uint64" :
103+ max = v .max ()
104+ min = v .min ()
105+ if max <= uint8max and min >= 0 :
106+ v = v .astype ("uint8" )
107+ elif max <= uint16max and min >= 0 :
108+ v = v .astype ("uint16" )
109+ elif max <= uint32max and min >= 0 :
110+ v = v .astype ("uint32" )
111+ else :
112+ return v
113+
114+ dtype = str (v .dtype )
115+
116+ if dtype in plotlyjsShortTypes :
117+ arrObj = {
118+ "dtype" : plotlyjsShortTypes [dtype ],
119+ "bdata" : base64 .b64encode (v ).decode ("ascii" ),
120+ }
121+
122+ if v .ndim > 1 :
123+ arrObj ["shape" ] = str (v .shape )[1 :- 1 ]
124+
125+ return arrObj
126+
127+ return v
128+
129+
53130def copy_to_readonly_numpy_array (v , kind = None , force_numeric = False ):
54131 """
55132 Convert an array-like value into a read-only numpy array
@@ -415,7 +492,7 @@ def validate_coerce(self, v):
415492 # Pass typed array spec through
416493 pass
417494 elif is_homogeneous_array (v ):
418- v = copy_to_readonly_numpy_array (v )
495+ v = to_typed_array_spec (v )
419496 elif is_simple_array (v ):
420497 v = to_scalar_or_list (v )
421498 else :
0 commit comments