Skip to content

Commit

Permalink
Merge pull request #4013 from plotly/angle_arrayOk
Browse files Browse the repository at this point in the history
angle can now be arrayOK
  • Loading branch information
nicolaskruchten authored Jan 11, 2023
2 parents 1e9e4bd + 6660820 commit 488f117
Show file tree
Hide file tree
Showing 74 changed files with 209 additions and 153 deletions.
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

0 comments on commit 488f117

Please sign in to comment.