Plotly.py: Is there a way to do real time plotting in the notebook offline mode?

Created on 21 Mar 2016  路  8Comments  路  Source: plotly/plotly.py

The question above, is there a way to rerender the graph?

All 8 comments

Hi, I have looked there appears to be no way to do this, I am writing the code to do it however, I have actually been looking at the architecture, it looks simple to do.

class OfflineStream:
    """
    Interface to Plotly's real-time graphing API.
    Initialize a Stream object with a stream_id
    found in {plotly_domain}/settings.
    Real-time graphs are initialized with a call to `plot` that embeds
    your unique `stream_id`s in each of the graph's traces. The `Stream`
    interface plots data to these traces, as identified with the unique
    stream_id, in real-time.
    Every viewer of the graph sees the same data at the same time.
    View examples and tutorials here:
    https://plot.ly/python/streaming/
    Stream example:
    # Initialize a streaming graph
    # by embedding stream_id's in the graph's traces
    import plotly.plotly as py
    from plotly.graph_objs import Data, Scatter, Stream
    stream_id = "your_stream_id" # See {plotly_domain}/settings
    py.plot(Data([Scatter(x=[], y=[],
                          stream=Stream(token=stream_id, maxpoints=100))]))
    # Stream data to the import trace
    stream = Stream(stream_id) # Initialize a stream object
    stream.open() # Open the stream
    stream.write(dict(x=1, y=1)) # Plot (1, 1) in your graph
    """

    # Static instances of offline streams
    # id -> stream to write
    _offlineStreamInstances = {}
    @utils.template_doc(**tools.get_config_file())
    def __init__(self, stream_id):

        # Store the stream offline to be referenced later.
        if stream_id in _offlineStreamInstances.keys():

            self = _offlineStreamInstances[stream_id]
        else:
            """
            Initialize a Stream object with your unique stream_id.
            Find your stream_id at {plotly_domain}/settings.
            For more help, see: `help(plotly.plotly.Stream)`
            or see examples and tutorials here:
            https://plot.ly/python/streaming/
            """
            self.stream_id = stream_id
            self.connected = False
            self._stream = None
            _offlineStreamInstances[stream_id] = self

def write(self, trace, layout=None, validate=True,
              reconnect_on=(200, '', 408)):
        """
        Write to an open stream.
        Once you've instantiated a 'Stream' object with a 'stream_id',
        you can 'write' to it in real time.
        positional arguments:
        trace - A valid plotly trace object (e.g., Scatter, Heatmap, etc.).
                Not all keys in these are `stremable` run help(Obj) on the type
                of trace your trying to stream, for each valid key, if the key
                is streamable, it will say 'streamable = True'. Trace objects
                must be dictionary-like.
        keyword arguments:
        layout (default=None) - A valid Layout object
                                Run help(plotly.graph_objs.Layout)
        validate (default = True) - Validate this stream before sending?
                                    This will catch local errors if set to
                                    True.
        Some valid keys for trace dictionaries:
            'x', 'y', 'text', 'z', 'marker', 'line'
        Examples:
        >>> write(dict(x=1, y=2))  # assumes 'scatter' type
        >>> write(Bar(x=[1, 2, 3], y=[10, 20, 30]))
        >>> write(Scatter(x=1, y=2, text='scatter text'))
        >>> write(Scatter(x=1, y=3, marker=Marker(color='blue')))
        >>> write(Heatmap(z=[[1, 2, 3], [4, 5, 6]]))
        The connection to plotly's servers is checked before writing
        and reconnected if disconnected and if the response status code
        is in `reconnect_on`.
        For more help, see: `help(plotly.plotly.Stream)`
        or see examples and tutorials here:
        http://nbviewer.ipython.org/github/plotly/python-user-guide/blob/master/s7_streaming/s7_streaming.ipynb
        """
        stream_object = dict()
        stream_object.update(trace)
        if 'type' not in stream_object:
            stream_object['type'] = 'scatter'
        if validate:
            try:
                tools.validate(stream_object, stream_object['type'])
            except exceptions.PlotlyError as err:
                raise exceptions.PlotlyError(
                    "Part of the data object with type, '{0}', is invalid. "
                    "This will default to 'scatter' if you do not supply a "
                    "'type'. If you do not want to validate your data objects "
                    "when streaming, you can set 'validate=False' in the call "
                    "to 'your_stream.write()'. Here's why the object is "
                    "invalid:\n\n{1}".format(stream_object['type'], err)
                )
            if layout is not None:
                try:
                    tools.validate(layout, 'Layout')
                except exceptions.PlotlyError as err:
                    raise exceptions.PlotlyError(
                        "Your layout kwarg was invalid. "
                        "Here's why:\n\n{0}".format(err)
                    )
        del stream_object['type']

        if layout is not None:
            stream_object.update(dict(layout=layout))

        # TODO: allow string version of this?
        jdata = json.dumps(stream_object, cls=utils.PlotlyJSONEncoder)
        jdata += "\n"

// UPDATE GRAPH HERE via redraw ??? method? The graph must be able to take somekind of json
        try:
            self._stream.write(jdata, reconnect_on=reconnect_on)
        except AttributeError:
            raise exceptions.PlotlyError(
                "Stream has not been opened yet, "
                "cannot write to a closed connection. "
                "Call `open()` on the stream to open the stream.")

I need the code to update the graph I am not quite sure how it is done, on the client side.

Please ask questions about using the Plotly Python client at community.plot.ly or http://stackoverflow.com/questions/tagged/plotly

This issue was previously discussed here: https://github.com/plotly/plotly.js/issues/16 where @chriddyp recommended to open a related feature request over here. Maybe @jackparmer could kindly reconsider to open this again as a feature request?

@ArEnSc did you find a way to actually do this and if yes, did you submit a pull request for these guys to review ?

Nope you cannot do this sadly, would have made a nice feature

I recently asked basically the same question here, and didn't get a satisfying response. A cheap workaround is to use IPython.display.clear_output, assuming the iplot is your only output for that cell, but having offline iplot updating as a feature still would be nice!

I recently uses ipywidgets to update the JaveScript. The main codes can be found in here.

I am not familiar with the plotly stream object so I generate a new plotly plot each time. The main features of the above codes are:

  1. update JavaScript without using IPython.display.display, so the notebook does not blow up.
  2. update the <div> directly without IPython.display.clear_output.

If updating the stream object requires a JavaScript update, the code in the above link can serve as a good way to update the JaveScript.

This has been possible since 3.0.0 using FigureWidget

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vlizanae picture vlizanae  路  4Comments

binaryfunt picture binaryfunt  路  5Comments

keithjjones picture keithjjones  路  3Comments

jonmmease picture jonmmease  路  3Comments

fcollonval picture fcollonval  路  3Comments