Skip to content

Converting go.Figure into go.FigureWidget causes error for date axis #3075

@stephprobst

Description

@stephprobst

Converting a go.Figure object into a go.FigureWidget object causes a serialization error.

Environment:

Plotly version: 4.14.1
Jupyter Lab version: 3.0.0
Windows 10

Sample code:

import plotly.graph_objects as go
from datetime import date
fig = go.Figure(data=go.Bar(
    x=[date(2017,1,1), date(2017,1,2), date(2017,1,3)],
    y=[2, 3, 1]))
go.FigureWidget(fig)

Error:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-21-73510c9ecfe4> in <module>
      1 fig = my_chart.plotly_figure
----> 2 go.FigureWidget(fig)
C:\ProgramData\Anaconda3\lib\site-packages\plotly\graph_objs\_figurewidget.py in __init__(self, data, layout, frames, skip_invalid, **kwargs)
    594             is invalid AND skip_invalid is False
    595         """
--> 596         super(FigureWidget, self).__init__(data, layout, frames, skip_invalid, **kwargs)
    597 
    598     def add_area(
C:\ProgramData\Anaconda3\lib\site-packages\plotly\basewidget.py in __init__(self, data, layout, frames, skip_invalid, **kwargs)
    115         # with the `layout` constructor parameter of the `widgets.DOMWidget`
    116         # ipywidgets class
--> 117         super(BaseFigureWidget, self).__init__(
    118             data=data,
    119             layout_plotly=layout,
C:\ProgramData\Anaconda3\lib\site-packages\plotly\basedatatypes.py in __init__(self, data, layout_plotly, frames, skip_invalid, **kwargs)
    524         # The _data property is a list of dicts containing the properties
    525         # explicitly set by the user for each trace.
--> 526         self._data = [deepcopy(trace._props) for trace in data]
    527 
    528         # ### Create data defaults ###
C:\ProgramData\Anaconda3\lib\site-packages\plotly\basedatatypes.py in __setattr__(self, prop, value)
    719         if prop.startswith("_") or hasattr(self, prop):
    720             # Let known properties and private properties through
--> 721             super(BaseFigure, self).__setattr__(prop, value)
    722         else:
    723             # Raise error on unknown public properties
C:\ProgramData\Anaconda3\lib\site-packages\traitlets\traitlets.py in __set__(self, obj, value)
    583             raise TraitError('The "%s" trait is read-only.' % self.name)
    584         else:
--> 585             self.set(obj, value)
    586 
    587     def _validate(self, obj, value):
C:\ProgramData\Anaconda3\lib\site-packages\traitlets\traitlets.py in set(self, obj, value)
    572             # we explicitly compare silent to True just in case the equality
    573             # comparison above returns something other than True/False
--> 574             obj._notify_trait(self.name, old_value, new_value)
    575 
    576     def __set__(self, obj, value):
C:\ProgramData\Anaconda3\lib\site-packages\traitlets\traitlets.py in _notify_trait(self, name, old_value, new_value)
   1132 
   1133     def _notify_trait(self, name, old_value, new_value):
-> 1134         self.notify_change(Bunch(
   1135             name=name,
   1136             old=old_value,
C:\ProgramData\Anaconda3\lib\site-packages\ipywidgets\widgets\widget.py in notify_change(self, change)
    603             if name in self.keys and self._should_send_property(name, getattr(self, name)):
    604                 # Send new state to front-end
--> 605                 self.send_state(key=name)
    606         super(Widget, self).notify_change(change)
    607 
C:\ProgramData\Anaconda3\lib\site-packages\ipywidgets\widgets\widget.py in send_state(self, key)
    487             state, buffer_paths, buffers = _remove_buffers(state)
    488             msg = {'method': 'update', 'state': state, 'buffer_paths': buffer_paths}
--> 489             self._send(msg, buffers=buffers)
    490 
    491 
C:\ProgramData\Anaconda3\lib\site-packages\ipywidgets\widgets\widget.py in _send(self, msg, buffers)
    735         """Sends a message to the model in the front-end."""
    736         if self.comm is not None and self.comm.kernel is not None:
--> 737             self.comm.send(data=msg, buffers=buffers)
    738 
    739     def _repr_keys(self):
C:\ProgramData\Anaconda3\lib\site-packages\ipykernel\comm\comm.py in send(self, data, metadata, buffers)
    120     def send(self, data=None, metadata=None, buffers=None):
    121         """Send a message to the frontend-side version of this comm"""
--> 122         self._publish_msg('comm_msg',
    123             data=data, metadata=metadata, buffers=buffers,
    124         )
C:\ProgramData\Anaconda3\lib\site-packages\ipykernel\comm\comm.py in _publish_msg(self, msg_type, data, metadata, buffers, **keys)
     63         data = {} if data is None else data
     64         metadata = {} if metadata is None else metadata
---> 65         content = json_clean(dict(data=data, comm_id=self.comm_id, **keys))
     66         self.kernel.session.send(self.kernel.iopub_socket, msg_type,
     67             content,
C:\ProgramData\Anaconda3\lib\site-packages\ipykernel\jsonutil.py in json_clean(obj)
    189         out = {}
    190         for k,v in iteritems(obj):
--> 191             out[unicode_type(k)] = json_clean(v)
    192         return out
    193     if isinstance(obj, datetime):
C:\ProgramData\Anaconda3\lib\site-packages\ipykernel\jsonutil.py in json_clean(obj)
    189         out = {}
    190         for k,v in iteritems(obj):
--> 191             out[unicode_type(k)] = json_clean(v)
    192         return out
    193     if isinstance(obj, datetime):
C:\ProgramData\Anaconda3\lib\site-packages\ipykernel\jsonutil.py in json_clean(obj)
    189         out = {}
    190         for k,v in iteritems(obj):
--> 191             out[unicode_type(k)] = json_clean(v)
    192         return out
    193     if isinstance(obj, datetime):
C:\ProgramData\Anaconda3\lib\site-packages\ipykernel\jsonutil.py in json_clean(obj)
    175 
    176     if isinstance(obj, list):
--> 177         return [json_clean(x) for x in obj]
    178 
    179     if isinstance(obj, dict):
C:\ProgramData\Anaconda3\lib\site-packages\ipykernel\jsonutil.py in <listcomp>(.0)
    175 
    176     if isinstance(obj, list):
--> 177         return [json_clean(x) for x in obj]
    178 
    179     if isinstance(obj, dict):
C:\ProgramData\Anaconda3\lib\site-packages\ipykernel\jsonutil.py in json_clean(obj)
    189         out = {}
    190         for k,v in iteritems(obj):
--> 191             out[unicode_type(k)] = json_clean(v)
    192         return out
    193     if isinstance(obj, datetime):
C:\ProgramData\Anaconda3\lib\site-packages\ipykernel\jsonutil.py in json_clean(obj)
    175 
    176     if isinstance(obj, list):
--> 177         return [json_clean(x) for x in obj]
    178 
    179     if isinstance(obj, dict):
C:\ProgramData\Anaconda3\lib\site-packages\ipykernel\jsonutil.py in <listcomp>(.0)
    175 
    176     if isinstance(obj, list):
--> 177         return [json_clean(x) for x in obj]
    178 
    179     if isinstance(obj, dict):
C:\ProgramData\Anaconda3\lib\site-packages\ipykernel\jsonutil.py in json_clean(obj)
    195 
    196     # we don't understand it, it's probably an unserializable object
--> 197     raise ValueError("Can't clean for JSON: %r" % obj)
ValueError: Can't clean for JSON: datetime.date(2017, 1, 1)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions