<div dir="ltr"><div>Hey IPython Community --</div><div><br></div><div>I wanted to share with you Plotly's new IPython graph widget. A couple GIFs:</div><div><br></div><div><a href="http://nbviewer.ipython.org/gist/chriddyp/9827cb5086cfab8da092/Widgets%20-%20Contour%20Plotter.ipynb">Contour Plot Explorer</a> - The bottom graph updates with the elevation and distance of the points that are clicked on in the top-graph.</div><div><img src="http://i.imgur.com/2Wbbo6l.gif" width="386" height="455"></div><div>(Link to GIF: <a href="http://i.imgur.com/2Wbbo6l.gif">http://i.imgur.com/2Wbbo6l.gif</a>)</div><div><br></div><div><br></div><div><a href="http://nbviewer.ipython.org/gist/chriddyp/9827cb5086cfab8da092/Pandas%20Widget%20-%20Time%20Series,%20Search,%20and%20Filtering.ipynb">Dataframe Explorer of NYC 311 calls</a>: Zooming and panning in the top time-series graph updates the bottom graph. Updating the search, dropdown, and slider values perform Pandas calls and Plotly restyle commands.</div><div><br><img src="http://i.imgur.com/h5GLIHc.gif" width="443" height="562"></div><div>(Link to GIF: <a href="http://i.imgur.com/h5GLIHc.gif">http://i.imgur.com/h5GLIHc.gif</a>)<br><br></div><div><br></div><div><br></div><div>This involved a couple of neat interactions with the Widget framework:</div><div>- Events from our JS graphing library (hover, click, zoom) get passed to the Python kernel. Python callbacks can be assigned with e.g. <font face="monospace, monospace">GraphWidget.on_click(callback)</font></div><div><br></div><div>- All the functions from our JS graphing lib are exposed in the Python GraphWidget: <font face="monospace, monospace">restyle</font>, <font face="monospace, monospace">add_traces</font>, <font face="monospace, monospace">delete_traces</font>, <font face="monospace, monospace">reorder_traces</font>, <font face="monospace, monospace">relayout</font></div><div><br></div><div>- We're embedded these graphs as IFrames and all communication from the IPython JS client happens through postMessage. Since the GraphWidget is initialized with the unique URL of the graph, it's possible to swap graphs in and out of IPython widgets. For example, <a href="http://nbviewer.ipython.org/9827cb5086cfab8da092/Widgets%20-%20Contour%20Plotter.ipynb">that Contour Plot Explorer</a> will work with any Contour Plot, the user just has to replace <font face="monospace, monospace">contour_plot = GraphWidget('<a href="https://plot.ly/~bronsolo/63">https://plot.ly/~bronsolo/63</a>') </font><font face="arial, helvetica, sans-serif">with a URL of their own contour plot.</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">The widget code is here: <a href="https://github.com/plotly/python-api/tree/master/plotly/widgets">https://github.com/plotly/python-api/tree/master/plotly/widgets</a>. Any feedback or suggestions is greatly appreciated!</font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif">Some comments from the development POV: <br>- JS tracebacks were really difficult to debug. </font></div><div><font face="arial, helvetica, sans-serif">- For easy use by the user, I decided to<a href="https://github.com/plotly/python-api/blob/master/plotly/widgets/graph_widget.py#L17-L22"> inject the JS dynamically on import</a>. Adding <a href="https://github.com/plotly/python-api/blob/master/plotly/widgets/graphWidget.js#L129">//@ source</a> to the end of the injected JS made the JS code appear in Chrome's dev tools. Without </font><font face="monospace, monospace">//@ source, the </font><font face="arial, helvetica, sans-serif">dynamic JS was lost in a Chrome VM.</font></div><div><font face="arial, helvetica, sans-serif">- I'm using </font><font face="monospace, monospace">Unicode(sync=True) </font><font face="arial, helvetica, sans-serif">to pass messages back and forth, but really I felt like I should just be using the underlying </font><font face="monospace, monospace">comm</font><font face="arial, helvetica, sans-serif"> interface instead of the MVC framework. But, I had trouble finding good documentation on that interface.</font></div><div><font face="arial, helvetica, sans-serif">- Looking forward to a "knob" widget fora <a href="http://nbviewer.ipython.org/gist/chriddyp/9827cb5086cfab8da092/Widgets%20-%20Sliders%20and%20Etch-A-Sketch.ipynb">ipython etch-a-sketch</a> ;) </font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div><font face="arial, helvetica, sans-serif"><a href="http://nbviewer.ipython.org/gist/chriddyp/9827cb5086cfab8da092">Here are a few notebooks</a> demonstrating the graph widget, including <a href="http://nbviewer.ipython.org/gist/chriddyp/9827cb5086cfab8da092">an overview</a>. </font></div><div><font face="arial, helvetica, sans-serif"><br></font></div><div>Finally, thanks a bunch to the IPython team for all the great work with widgets!</div><div><br></div><div>Chris</div><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr">Chris Parmer<div>514 571 5897</div><div><a href="https://plot.ly/team" target="_blank">https://plot.ly/team</a></div></div></div>
</div>