Repository navigation
Conversation
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Link to issue
Reported in plotly/dash#4065. The Dash side is plotly/dash#4067.
Description of change
to_json_plotlyandPlotlyJSONEncoderno longer deep copy figures, and with orjson only the values orjson can't serialize go throughclean_to_json_compatible.BaseFigure._to_json_dict()andBasePlotlyType._to_json_dict()return the object's data without the deepcopy thatto_dict()/to_plotly_json()do. Typed arrays are converted with a newto_base64_copy, which copies only the containers it changes, so the figure is never mutated. Subclasses that overrideto_dictorto_plotly_jsonstill go through their override.default=toorjson.dumps, so one non-native value (ago.Figure, apd.Timestamp) no longer sends the whole payload through the Python walk. Anything that still fails takes the old path, so errors are unchanged.PlotlyJSONEncoder.defaultuses_to_json_dictand returnsisoformat()for plaindatetime/date. Subclasses keep the old method order, so theirencode_as_*overrides still apply.Demo
10 traces x 20k points,
to_json_plotlymedian ms, before -> after:go.Figurego.Figure{"f": go.Figure, "t": pd.Timestamp}{"f": go.Figure, "t": pd.Timestamp}go.Figure{"f": go.Figure, "t": pd.Timestamp}Output is byte-identical to
mainon both engines, pretty and compact, for px figures, frames, templates, geojson, tuples, numpy/pandas/datetime/Decimal/NaN values, and mixed dicts. Known differences, both with orjson:datetime64array sitting next to a value orjson can't serialize now uses orjson's form (2024-01-01T05:00:00) instead ofdatetime_as_string(2024-01-01T05:00:00.000000000). That is the same output you already get when the array is on its own.TypeError: Type is not JSON serializable: NaTTypenow serialize, as they already did with the json engine.Testing strategy
test_figure_is_not_deep_copied(all engines) fails serialization ifdeepcopyis called, checks the output againstto_dict(), and checks that the figure's numpy arrays are left as they were.test_to_base64_copy_leaves_input_untouchedcovers the copy-on-write helper.test_subclass_overrides_are_keptandtest_encoder_subclass_overrides_are_keptcover subclasses that overrideto_dict/to_plotly_jsonand the encoder'sencode_as_*methods.tests/test_io,tests/test_core,tests/test_plotly_utilsandtests/test_optionalpass locally, apart from failures that also happen onmainhere (test_trendline_on_timeseries[pyarrow-*]and a colorscale test that depends on test order).Guidelines