Skip to content
Open
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
Treat range() as a simple array
Fixes #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
commit f8deca071f5da5039c2c674055a1e4ea6ef4d06a
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