plotly / plotly.py

The interactive graphing library for Python :sparkles: This project now includes Plotly Express!
https://plotly.com/python/
MIT License
15.62k stars 2.51k forks source link

Treat range() as a simple array #4636

Open dniku opened 1 week ago

dniku commented 1 week ago

Fixes https://github.com/plotly/plotly.py/issues/1798 (incorrectly closed during a recent cleanup).

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

Previously the following code

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)

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.