Skip to content

Commit

Permalink
Treat range() as a simple array
Browse files Browse the repository at this point in the history
Fixes plotly#1798 (incorrectly closed during a recent cleanup).

Allows range() to be passed where simple arrays are expected.

Previously the following code

```python
import plotly.graph_objects as go
go.Figure(go.Scatter(x=range(3), y=[3, 2, 1]))
```

failed with

```
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-1-be3f9396b95f> in <cell line: 2>()
      1 import plotly.graph_objects as go
----> 2 go.Figure(go.Scatter(x=range(3), y=[3, 2, 1]))

5 frames
/usr/local/lib/python3.10/dist-packages/plotly/graph_objs/_scatter.py in __init__(self, arg, alignmentgroup, cliponaxis, connectgaps, customdata, customdatasrc, dx, dy, error_x, error_y, fill, fillcolor, fillpattern, groupnorm, hoverinfo, hoverinfosrc, hoverlabel, hoveron, hovertemplate, hovertemplatesrc, hovertext, hovertextsrc, ids, idssrc, legend, legendgroup, legendgrouptitle, legendrank, legendwidth, line, marker, meta, metasrc, mode, name, offsetgroup, opacity, orientation, selected, selectedpoints, showlegend, stackgaps, stackgroup, stream, text, textfont, textposition, textpositionsrc, textsrc, texttemplate, texttemplatesrc, uid, uirevision, unselected, visible, x, x0, xaxis, xcalendar, xhoverformat, xperiod, xperiod0, xperiodalignment, xsrc, y, y0, yaxis, ycalendar, yhoverformat, yperiod, yperiod0, yperiodalignment, ysrc, **kwargs)
   3476         _v = x if x is not None else _v
   3477         if _v is not None:
-> 3478             self["x"] = _v
   3479         _v = arg.pop("x0", None)
   3480         _v = x0 if x0 is not None else _v

/usr/local/lib/python3.10/dist-packages/plotly/basedatatypes.py in __setitem__(self, prop, value)
   4871                 # ### Handle simple property ###
   4872                 else:
-> 4873                     self._set_prop(prop, value)
   4874             else:
   4875                 # Make sure properties dict is initialized

/usr/local/lib/python3.10/dist-packages/plotly/basedatatypes.py in _set_prop(self, prop, val)
   5215                 return
   5216             else:
-> 5217                 raise err
   5218 
   5219         # val is None

/usr/local/lib/python3.10/dist-packages/plotly/basedatatypes.py in _set_prop(self, prop, val)
   5210 
   5211         try:
-> 5212             val = validator.validate_coerce(val)
   5213         except ValueError as err:
   5214             if self._skip_invalid:

/usr/local/lib/python3.10/dist-packages/_plotly_utils/basevalidators.py in validate_coerce(self, v)
    401             v = to_scalar_or_list(v)
    402         else:
--> 403             self.raise_invalid_val(v)
    404         return v
    405 

/usr/local/lib/python3.10/dist-packages/_plotly_utils/basevalidators.py in raise_invalid_val(self, v, inds)
    285                 name += "[" + str(i) + "]"
    286 
--> 287         raise ValueError(
    288             """
    289     Invalid value of type {typ} received for the '{name}' property of {pname}

ValueError: 
    Invalid value of type 'builtins.range' received for the 'x' property of scatter
        Received value: range(0, 3)

    The 'x' property is an array that may be specified as a tuple,
    list, numpy array, or pandas Series
```

(tested via [Google Colab](https://colab.research.google.com/notebooks/empty.ipynb))

After this change, it is possible to use `range()` in this context.

A potential concern is Python 2 support — there, `range()` is a plain list. I have not tested this with Python 2.
  • Loading branch information
dniku authored Jun 15, 2024
1 parent 51eb5ea commit f8deca0
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions packages/python/plotly/_plotly_utils/basevalidators.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def to_scalar_or_list(v):
pd = get_module("pandas", should_load=False)
if np and np.isscalar(v) and hasattr(v, "item"):
return v.item()
if isinstance(v, (list, tuple)):
if is_simple_array(v):
return [to_scalar_or_list(e) for e in v]
elif np and isinstance(v, np.ndarray):
if v.ndim == 0:
Expand Down Expand Up @@ -211,7 +211,7 @@ def is_simple_array(v):
"""
Return whether a value is considered to be an simple array
"""
return isinstance(v, (list, tuple))
return isinstance(v, (list, tuple, range))


def is_array(v):
Expand Down

0 comments on commit f8deca0

Please sign in to comment.