Skip to content

Accept None elements in color, number and angle arrays so from_json loads figures with NaN - #5856

Open
Thanatos9404 wants to merge 2 commits into
plotly:mainfrom
Thanatos9404:fix-from-json-nan-arrays
Open

Thanatos9404 wants to merge 2 commits into
plotly:mainfrom
Thanatos9404:fix-from-json-nan-arrays

Conversation

@Thanatos9404

Copy link
Copy Markdown

Link to issue

Closes #4280

Description of change

to_json writes NaN as null, and from_json loads that back as None. ColorValidator, NumberValidator and AngleValidator rejected None inside lists. So a figure with NaN in a list for a property that accepts NaN, such as marker.color=[0, np.nan] with a colorscale, marker.angle or a bar offset, could be written with to_json but not loaded again. As suggested in the issue, these validators now accept and keep None elements inside arrays. plotly.js already receives null for these values today, since that is what to_json sends, so what gets drawn doesn't change.

Demo

import numpy as np
import plotly.graph_objects as go
import plotly.io as pio

fig = go.Figure(go.Scatter(x=[0, 0], y=[0, 1], marker={"color": [0, np.nan]}))
fig2 = pio.from_json(fig.to_json())
# main:        ValueError: Invalid element(s) received for the 'color' property of scatter.marker
#                  Invalid elements include: [None]
# this branch: fig2.data[0].marker.color == (0, None)

Testing strategy

New validator tests check that None elements are accepted and kept in lists for all three validators (and in object arrays for colors), with and without min/max or a colorscale. They also check that an invalid element next to a None is still reported, without the None. test_from_json_nan_in_arrays round-trips a scatter marker.color and marker.angle and a bar offset containing NaN. The new tests fail on main and pass with this change.

Locally (Windows, Python 3.12) I ran tests/test_core, tests/test_io, tests/test_plotly_utils and tests/test_optional. The same 53 tests fail on main and on this branch in this environment, mostly because optional packages such as statsmodels aren't installed, plus Windows file-encoding errors in the offline HTML tests. Nothing else fails. ruff format --check . passes.

Additional information (optional)

  • Inputs that already worked: numpy, pandas and polars inputs already round-trip on main, because they are serialized as typed arrays (bdata). Only lists and tuples hit this.
  • Newly accepted: lists such as marker.size=[1, None] or textfont.color=["red", None] are now accepted, where they used to raise. NaN in the arrays of bounded properties such as marker.size and marker.opacity is still rejected when the figure is built (test_rejection_aok_min_max), so those never reach to_json with a NaN. This PR leaves that as it is.
  • Unchanged: scalars keep their meaning, where None means the property is unset. IntegerValidator is also unchanged, since its lists can't hold NaN in the first place.

Guidelines

to_json writes NaN as null and from_json loads it back as None, which
ColorValidator, NumberValidator and AngleValidator rejected inside
lists, so figures with NaN in these arrays could not be loaded again.
Keep None elements in arrays; scalars are unchanged.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

to_json does not handle color as np.nan properly

1 participant