From f2784e57129849c5bc953213747d2aaa4b458fe0 Mon Sep 17 00:00:00 2001
From: Jon Mease <jon.mease@gmail.com>
Date: Tue, 24 Jul 2018 13:05:18 -0400
Subject: [PATCH] Add new interact and overview notebooks

---
 notebooks/Interact.ipynb |  92 ++++++
 notebooks/Overview.ipynb | 588 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 680 insertions(+)
 create mode 100644 notebooks/Interact.ipynb
 create mode 100644 notebooks/Overview.ipynb

diff --git a/notebooks/Interact.ipynb b/notebooks/Interact.ipynb
new file mode 100644
index 0000000..b989e38
--- /dev/null
+++ b/notebooks/Interact.ipynb
@@ -0,0 +1,92 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Interact\n",
+    "Here is a simple example of using the `interact` decorator from ipywidgets to create a simple set of widgets to control the parameters of a plot"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import plotly.graph_objs as go\n",
+    "import numpy as np\n",
+    "from ipywidgets import interact"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "First we'll create an empty figure, and add an empty scatter trace to it."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "fig = go.FigureWidget()\n",
+    "scatt = fig.add_scatter()\n",
+    "fig"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Then, write an update function that inputs the frequency factor (`a`) and phase factor (`b`) and sets the `x` and `y` properties of the scatter trace.  This function is decorated with the `interact` decorator from the `ipywidgets` package. The decorator parameters are used to specify the ranges of parameters that we want to sweep over. See http://ipywidgets.readthedocs.io/en/latest/examples/Using%20Interact.html for more details."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "xs=np.linspace(0, 6, 100)\n",
+    "\n",
+    "@interact(a=(1.0, 4.0, 0.01), b=(0, 10.0, 0.01), color=['red', 'green', 'blue'])\n",
+    "def update(a=3.6, b=4.3, color='blue'):\n",
+    "    with fig.batch_update():\n",
+    "        scatt.x=xs\n",
+    "        scatt.y=np.sin(a*xs-b)\n",
+    "        scatt.line.color=color"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.6.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/notebooks/Overview.ipynb b/notebooks/Overview.ipynb
new file mode 100644
index 0000000..1f96945
--- /dev/null
+++ b/notebooks/Overview.ipynb
@@ -0,0 +1,588 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Overview\n",
+    "\n",
+    "This notebook introduces some of the new features of plotly.py version 3\n",
+    "\n",
+    "## New Features\n",
+    "\n",
+    " - New `FigureWidget` class that is an ipywidget for displaying offline plotly figures.\n",
+    " - Traces can be added and updated interactively by simply assigning to properties\n",
+    " - The full Traces and Layout API is generated from the plotly schema to provide a great experience for interactive use in the notebook.\n",
+    " - Data validation covering the full API with clear, informative error messages.\n",
+    " - Jupyter friendly docstrings on constructor params and properties.\n",
+    " - Support for setting array properties as numpy arrays. When numpy arrays are used, ipywidgets binary serialization protocol is used to avoid converting these to JSON strings.\n",
+    " - Context manager API for animation."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Imports"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# pandas\n",
+    "import pandas as pd\n",
+    "\n",
+    "# numpy\n",
+    "import numpy as np\n",
+    "\n",
+    "# scikit learn\n",
+    "from sklearn import datasets"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Load iris dataset\n",
+    "iris_data = datasets.load_iris()\n",
+    "feature_names = [name.replace(' (cm)', '').replace(' ', '_') for name in iris_data.feature_names]\n",
+    "iris_df = pd.DataFrame(iris_data.data, columns=feature_names)\n",
+    "iris_class = iris_data.target + 1\n",
+    "iris_df.head()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Create and display an empty FigureWidget\n",
+    "A FigureWidget behaves almost identically to a Figure but it is also an ipywidget that can be displayed directly in the notebook without calling `iplot`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import plotly.graph_objs as go"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "f1 = go.FigureWidget()\n",
+    "f1"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Tab completion \n",
+    "Entering ``f1.add_<tab>`` displays add methods for all of the supported trace types"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# f1.add_"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Entering ``f1.add_scatter(<tab>)`` displays the names of all of the top-level properties for the scatter trace type\n",
+    "\n",
+    "Entering ``f1.add_scatter(<shift+tab>)`` displays the signature pop-up. Expanding this pop-up reveals the method doc string which contains the descriptions of all of the top level properties"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# f1.add_scatter("
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Add scatter trace"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [],
+   "source": [
+    "scatt1 = f1.add_scatter(x=iris_df.sepal_length, y=iris_df.petal_width)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "scatt1.mode?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# That's not what we wanted, change the mode to 'markers'\n",
+    "scatt1.mode = 'markers'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Set size to 8\n",
+    "scatt1.marker.size = 8"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Color markers by iris class\n",
+    "scatt1.marker.color = iris_class"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Change colorscale\n",
+    "scatt1.marker.cmin = 0.5\n",
+    "scatt1.marker.cmax = 3.5\n",
+    "scatt1.marker.colorscale = [[0, 'red'], [0.33, 'red'], \n",
+    "                            [0.33, 'green'], [0.67, 'green'], \n",
+    "                            [0.67, 'blue'], [1.0, 'blue']]\n",
+    "\n",
+    "scatt1.marker.showscale = True"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Fix up colorscale ticks\n",
+    "scatt1.marker.colorbar.ticks = 'outside'\n",
+    "scatt1.marker.colorbar.tickvals = [1, 2, 3]\n",
+    "scatt1.marker.colorbar.ticktext = iris_data.target_names.tolist()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Set colorscale title\n",
+    "scatt1.marker.colorbar.title = 'Species'\n",
+    "scatt1.marker.colorbar.titlefont.size = 16\n",
+    "scatt1.marker.colorbar.titlefont.family = 'Rockwell'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Add axis labels\n",
+    "f1.layout.xaxis.title = 'sepal_length'\n",
+    "f1.layout.yaxis.title = 'petal_width'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Hover info\n",
+    "scatt1.text = iris_data.target_names[iris_data.target]\n",
+    "scatt1.hoverinfo = 'text+x+y'\n",
+    "f1.layout.hovermode = 'closest'"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Animate marker size change"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Set marker size based on petal_length\n",
+    "with f1.batch_animate(duration=1000):\n",
+    "    scatt1.marker.size = np.sqrt(iris_df.petal_length.values * 50)\n",
+    "    "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Restore constant marker size\n",
+    "with f1.batch_animate(duration=1000):\n",
+    "    scatt1.marker.size = 8"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Configure colorscale for brushing"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "scatt1.marker.colorbar = None\n",
+    "scatt1.marker.colorscale = [[0, 'lightgray'], [0.5, 'lightgray'], [0.5, 'red'], [1, 'red']]\n",
+    "scatt1.marker.cmin = -0.5\n",
+    "scatt1.marker.cmax = 1.5\n",
+    "scatt1.marker.colorbar.ticks = 'outside'\n",
+    "scatt1.marker.colorbar.tickvals = [0, 1]\n",
+    "scatt1.marker.colorbar.ticktext = ['unselected', 'selected']"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Reset colors to zeros (unselected)\n",
+    "scatt1.marker.color = np.zeros(iris_class.size)\n",
+    "selected = np.zeros(iris_class.size)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Configure brushing callback"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Assigning these variables here is not required. But doing so tricks Jupyter into \n",
+    "# providing property tab completion on the parameters to the brush function below\n",
+    "from plotly.callbacks import Points\n",
+    "trace, points = scatt1, Points()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def brush(trace, points, selector):\n",
+    "    inds = np.array(points.point_inds)\n",
+    "    if inds.size:\n",
+    "        selected[inds] = 1\n",
+    "        trace.marker.color = selected"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "scatt1.on_selection(brush)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now box or lasso select points on the figure and see them turn red"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Reset brush\n",
+    "selected = np.zeros(iris_class.size)\n",
+    "scatt1.marker.color = selected"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Create second plot with different features"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [],
+   "source": [
+    "f2 = go.FigureWidget(data=[\n",
+    "    go.Scatter(x=iris_df.petal_length, y=iris_df.sepal_width, mode='markers')])\n",
+    "f2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Set axis titles\n",
+    "f2.layout.xaxis.title = 'petal_length'\n",
+    "f2.layout.yaxis.title = 'sepal_width'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Grab trace reference\n",
+    "scatt2 = f2.data[0]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true,
+    "scrolled": false
+   },
+   "outputs": [],
+   "source": [
+    "# Set marker styles / colorbars to match between figures\n",
+    "scatt2.marker = scatt1.marker"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Configure brush on both plots to update both plots\n",
+    "def brush(trace, points, state):\n",
+    "    inds = np.array(points.point_inds)\n",
+    "    if inds.size:\n",
+    "        selected = scatt1.marker.color.copy()\n",
+    "        selected[inds] = 1\n",
+    "        scatt1.marker.color = selected\n",
+    "        scatt2.marker.color = selected    \n",
+    "    \n",
+    "scatt1.on_selection(brush)\n",
+    "scatt2.on_selection(brush)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Reset brush\n",
+    "def reset_brush(btn):\n",
+    "    selected = np.zeros(iris_class.size)\n",
+    "    scatt1.marker.color = selected\n",
+    "    scatt2.marker.color = selected"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# ipywidgets\n",
+    "from ipywidgets import HBox, VBox, Button"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Create reset button\n",
+    "button = Button(description=\"clear\")\n",
+    "button.on_click(reset_brush)\n",
+    "button"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Hide colorbar for figure 1\n",
+    "scatt1.marker.showscale = False"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Set dragmode to lasso for both plots\n",
+    "f1.layout.dragmode = 'lasso'\n",
+    "f2.layout.dragmode = 'lasso'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# Display two figures and the reset button\n",
+    "f1.layout.width = 500\n",
+    "f2.layout.width = 500"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "VBox([HBox([f1, f2]), button])"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.6.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
-- 
GitLab