plotly / plotly.py

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

FIgureWidget not working with nbviewer #1116

Closed tarzzz closed 6 years ago

tarzzz commented 6 years ago

Example Notebook: http://nbviewer.jupyter.org/gist/tarzzz/7aa6eb0673d5b11b55748c1dd9f74537#

The Plot is not displayed when the chart is viewed on nbviewer (or as the HTML version). Not sure if this is a bug, or if it is not intended to work in static views.

cc: @jonmmease

empet commented 6 years ago

@tarzz On my machine it works with both Python 2.7.13 and Plotly 3.1.0, respectively Python 3.6.4 and Plotly 3.1.1.

Have you installed ipywidgets?

tarzzz commented 6 years ago

@empet It works on my machine, but not on the external/HTML viewers (like nbviewer.jupyter.org).

empet commented 6 years ago

@tarzz

No, the plot is not displayed in nbviewer. As I understood you are working on this feature :)

empet commented 6 years ago

@tarzz Well, to be more precise I hope that the FigureWidget instances will be displayed in the notebooks uploaded to Plotly cloud, not those rendered by nbviewer.

empet commented 6 years ago

@tarzz In a comment to this issue https://github.com/jupyter-widgets/ipywidgets/issues/2063 is suggested how to get the widgets displayed in nbviewer. I followed the steps explained here: https://ipywidgets.readthedocs.io/en/latest/embedding.html#embedding-widgets-in-html-web-pages, but the FigureWidget isn't rendered: http://nbviewer.jupyter.org/gist/empet/f6a363e1d0140e69f5e9139bb742849f

jonmmease commented 6 years ago

The behavior I'm seeing is that the figure axes are being displayed, but not the data. Is that what you're both seeing?

I think this is an issue related to the way that numpy arrays are encoded as binary buffers. These buffers are stored as JavaScript TypedArrays in the JavaScript widget model. And when the buffers are saved (through the "Save notebook widget state" process), and then restored (when a page is viewed on nbviewer) they are not being restored as typed arrays, but as DataView objects.

To test the theory, here's a notebook with a figure that doesn't use numpy arrays. I saved widget state and pushed to GitHub and then loaded with nbviewer.

https://nbviewer.jupyter.org/github/jonmmease/plotly_ipywidget_notebooks/blob/master/notebooks/HelloWorldFigureWidget.ipynb

screen shot 2018-08-15 at 6 30 51 pm

I'm not quite sure what to do about it yet...

jonmmease commented 6 years ago

Hi @maartenbreddels,

I was wondering if you would be willing to share some of your sage widget wisdom with us here. For the plotly.py FigureWidget we store some arrays as TypedArrays in the JavaScript model. But when the widget model state is saved and then reloaded (on nbviewer for example) these typed arrays are restored as DataView objects. Do you have any suggestions for how to handle restoring these back into TypedArrays? Thanks!!!

empet commented 6 years ago

Hi @tarzz and @jonmmease,

I converted the np.arrays, x and y, to list and now the FigureWidget is displayed, but after selection, the selected points don't get red: http://nbviewer.jupyter.org/gist/empet/f6a363e1d0140e69f5e9139bb742849f

tarzzz commented 6 years ago

@empet :

but after selection, the selected points don't get red:

Selections will not work on nbviewer (or Plotly Cloud) because they need to interact with Jupyter Kernel to work, whereas nbviewer only offers static/HTML views.

It will not be interactive, but you should be able to render the "saved" state though.

jonmmease commented 6 years ago

See https://github.com/plotly/plotly.js/pull/2911 for a proposed solution

maartenbreddels commented 6 years ago

Make sure you have a custom serializer, take a look at for instance ipyvolume's ScatterModel. In the end the typed array will be converted to sth like {dtype: 'float64', value: at.buffer, shape: [ar.lenght]} ( it should be the inverse of the deserializer).

jonmmease commented 6 years ago

Thanks @maartenbreddels ! That's what I was missing.

@tarzzz , it looks like I should be able to fix this in the widget library without needing a change to Plotly.js after all (I'm still going to work on that Plotly.js change for other reasons, but I don't think it's critical for getting this working now).

jonmmease commented 6 years ago

Done in #1117