Skip to content
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

angle can now be arrayOK #4013

Merged
merged 5 commits into from
Jan 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
- Fixed the usage of some deprecated NumPy types which were removed in NumPy 1.24 [[#3997](https://github.com/plotly/plotly.py/pull/3997)]
- Fixed bug for trendlines with datetime axes [[#3683](https://github.com/plotly/plotly.py/issues/3683)]
- `marker.angle` attribute now accepts iterables where appropriate [[#4013](https://github.com/plotly/plotly.py/issues/4013)]

## [5.11.0] - 2022-10-27

Expand Down
31 changes: 26 additions & 5 deletions packages/python/plotly/_plotly_utils/basevalidators.py
Original file line number Diff line number Diff line change
Expand Up @@ -1660,24 +1660,29 @@ class AngleValidator(BaseValidator):
"description": "A number (in degree) between -180 and 180.",
"requiredOpts": [],
"otherOpts": [
"dflt"
"dflt",
"arrayOk"
]
},
"""

def __init__(self, plotly_name, parent_name, **kwargs):
def __init__(self, plotly_name, parent_name, array_ok=False, **kwargs):
super(AngleValidator, self).__init__(
plotly_name=plotly_name, parent_name=parent_name, **kwargs
)
self.array_ok = array_ok

def description(self):
desc = """\
The '{plotly_name}' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180{array_ok}.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).
""".format(
plotly_name=self.plotly_name
plotly_name=self.plotly_name,
array_ok=", or a list, numpy array or other iterable thereof"
if self.array_ok
else "",
)

return desc
Expand All @@ -1686,6 +1691,22 @@ def validate_coerce(self, v):
if v is None:
# Pass None through
pass
elif self.array_ok and is_homogeneous_array(v):
try:
v_array = copy_to_readonly_numpy_array(v, force_numeric=True)
except (ValueError, TypeError, OverflowError):
self.raise_invalid_val(v)
v = v_array # Always numeric numpy array
# Normalize v onto the interval [-180, 180)
v = (v + 180) % 360 - 180
elif self.array_ok and is_simple_array(v):
# Check numeric
invalid_els = [e for e in v if not isinstance(e, numbers.Number)]

if invalid_els:
self.raise_invalid_elements(invalid_els[:10])

v = [(x + 180) % 360 - 180 for x in to_scalar_or_list(v)]
elif not isinstance(v, numbers.Number):
self.raise_invalid_val(v)
else:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@

# Fixtures
# --------
@pytest.fixture()
def validator():
@pytest.fixture
def validator(request):
return AngleValidator("prop", "parent")


@pytest.fixture
def validator_aok(request):
return AngleValidator("prop", "parent", array_ok=True)


# Tests
# -----
# ### Test acceptance ###
Expand All @@ -36,3 +41,32 @@ def test_rejection(val, validator):
validator.validate_coerce(val)

assert "Invalid value" in str(validation_failure.value)


# ### Test acceptance ###
@pytest.mark.parametrize("val", [[0, 179, -179]])
def test_aok_acceptance(val, validator_aok):
assert validator_aok.validate_coerce(val) == val
assert validator_aok.validate_coerce(tuple(val)) == val
assert np.array_equal(validator_aok.validate_coerce(np.array(val)), np.array(val))


# ### Test coercion above 180 ###
@pytest.mark.parametrize(
"val,expected",
[(180, -180), (181, -179), (-180.25, 179.75), (540, -180), (-541, 179)],
)
def test_aok_coercion(val, expected, validator_aok):
assert validator_aok.validate_coerce([val]) == [expected]
assert np.array_equal(
validator_aok.validate_coerce(np.array([val])), np.array([expected])
)


# ### Test rejection ###
@pytest.mark.parametrize("val", [["hello"], [()], [[]], [set()], ["34"]])
def test_aok_rejection(val, validator_aok):
with pytest.raises(ValueError) as validation_failure:
validator_aok.validate_coerce(val)

assert "Invalid element(s)" in str(validation_failure.value)
4 changes: 2 additions & 2 deletions packages/python/plotly/plotly/graph_objs/_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -1374,8 +1374,8 @@ def textangle(self):
the maximum size in bars.

The 'textangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
4 changes: 2 additions & 2 deletions packages/python/plotly/plotly/graph_objs/_funnel.py
Original file line number Diff line number Diff line change
Expand Up @@ -1150,8 +1150,8 @@ def textangle(self):
the maximum size in bars.

The 'textangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
4 changes: 2 additions & 2 deletions packages/python/plotly/plotly/graph_objs/_histogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -1450,8 +1450,8 @@ def textangle(self):
the maximum size in bars.

The 'textangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
4 changes: 2 additions & 2 deletions packages/python/plotly/plotly/graph_objs/_parcoords.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,8 @@ def labelangle(self):
margins when `labelposition` is set to "bottom".

The 'labelangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
4 changes: 2 additions & 2 deletions packages/python/plotly/plotly/graph_objs/_pie.py
Original file line number Diff line number Diff line change
Expand Up @@ -970,8 +970,8 @@ def rotation(self):
some other angle.

The 'rotation' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
4 changes: 2 additions & 2 deletions packages/python/plotly/plotly/graph_objs/_sunburst.py
Original file line number Diff line number Diff line change
Expand Up @@ -1065,8 +1065,8 @@ def rotation(self):
default the first slice starts at 3 o'clock.

The 'rotation' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
4 changes: 2 additions & 2 deletions packages/python/plotly/plotly/graph_objs/_waterfall.py
Original file line number Diff line number Diff line change
Expand Up @@ -1173,8 +1173,8 @@ def textangle(self):
the maximum size in bars.

The 'textangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
4 changes: 2 additions & 2 deletions packages/python/plotly/plotly/graph_objs/box/_marker.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ def angle(self):
Sets the marker angle in respect to `angleref`.

The 'angle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
4 changes: 2 additions & 2 deletions packages/python/plotly/plotly/graph_objs/carpet/_aaxis.py
Original file line number Diff line number Diff line change
Expand Up @@ -1253,8 +1253,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
4 changes: 2 additions & 2 deletions packages/python/plotly/plotly/graph_objs/carpet/_baxis.py
Original file line number Diff line number Diff line change
Expand Up @@ -1253,8 +1253,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
4 changes: 2 additions & 2 deletions packages/python/plotly/plotly/graph_objs/cone/_colorbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
4 changes: 2 additions & 2 deletions packages/python/plotly/plotly/graph_objs/contour/_colorbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
4 changes: 2 additions & 2 deletions packages/python/plotly/plotly/graph_objs/heatmap/_colorbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@ def tickangle(self):
labels vertically.

The 'tickangle' property is a angle (in degrees) that may be
specified as a number between -180 and 180. Numeric values outside this
range are converted to the equivalent value
specified as a number between -180 and 180.
Numeric values outside this range are converted to the equivalent value
(e.g. 270 is converted to -90).

Returns
Expand Down
Loading