diff --git a/packages/python/plotly/_plotly_utils/utils.py b/packages/python/plotly/_plotly_utils/utils.py index 88f1a4000db..bb33e44140b 100644 --- a/packages/python/plotly/_plotly_utils/utils.py +++ b/packages/python/plotly/_plotly_utils/utils.py @@ -43,8 +43,10 @@ def to_typed_array_spec(v): """ v = copy_to_readonly_numpy_array(v) + # Skip b64 encoding if numpy is not installed, + # or if v is not a numpy array, or if v is empty np = get_module("numpy", should_load=False) - if not np or not isinstance(v, np.ndarray): + if not np or not isinstance(v, np.ndarray) or v.size == 0: return v dtype = str(v.dtype) diff --git a/packages/python/plotly/plotly/tests/test_io/test_to_from_json.py b/packages/python/plotly/plotly/tests/test_io/test_to_from_json.py index a932282bd36..0376855dec1 100644 --- a/packages/python/plotly/plotly/tests/test_io/test_to_from_json.py +++ b/packages/python/plotly/plotly/tests/test_io/test_to_from_json.py @@ -2,6 +2,7 @@ import plotly.io as pio import pytest import plotly +import numpy as np import json import os import tempfile @@ -259,3 +260,16 @@ def test_write_json_from_file_string(fig1, pretty, remove_uids): # Check contents that were written expected = pio.to_json(fig1, pretty=pretty, remove_uids=remove_uids) assert result == expected + + +def test_to_dict_empty_np_array_int64(): + fig = go.Figure( + [ + go.Bar( + x=np.array([], dtype="str"), + y=np.array([], dtype="int64"), + ) + ] + ) + # to_dict() should not raise an exception + fig.to_dict() diff --git a/packages/python/plotly/plotly/tests/test_optional/test_px/test_px.py b/packages/python/plotly/plotly/tests/test_optional/test_px/test_px.py index 157cb1fd2a1..e7a090bde21 100644 --- a/packages/python/plotly/plotly/tests/test_optional/test_px/test_px.py +++ b/packages/python/plotly/plotly/tests/test_optional/test_px/test_px.py @@ -360,3 +360,18 @@ def test_render_mode(backend): ) assert fig.data[0].type == "histogram2dcontour" assert fig.data[1].type == "scatter" + + +def test_empty_df_int64(backend): + # Load px data, then filter it such that the dataframe is empty + df = px.data.tips(return_type=backend) + df = nw.from_native(px.data.tips(return_type=backend)) + df_empty = df.filter(nw.col("day") == "banana").to_native() + + fig = px.scatter( + df_empty, + x="total_bill", + y="size", # size is an int64 column + ) + # to_dict() should not raise an exception + fig.to_dict()