This notebook introduces some of the new features of plotly.py version 3
FigureWidget
class that is an ipywidget for displaying offline plotly figures.# pandas
import pandas as pd
# numpy
import numpy as np
# scikit learn
from sklearn import datasets
# Apply hack to hide tracebacks for presentation
import hide_ipython_tbs
# Load iris dataset
iris_data = datasets.load_iris()
feature_names = [name.replace(' (cm)', '').replace(' ', '_') for name in iris_data.feature_names]
iris_df = pd.DataFrame(iris_data.data, columns=feature_names)
iris_class = iris_data.target + 1
iris_df.head()
sepal_length | sepal_width | petal_length | petal_width | |
---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 |
1 | 4.9 | 3.0 | 1.4 | 0.2 |
2 | 4.7 | 3.2 | 1.3 | 0.2 |
3 | 4.6 | 3.1 | 1.5 | 0.2 |
4 | 5.0 | 3.6 | 1.4 | 0.2 |
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
import plotly.graph_objs as go
f1 = go.FigureWidget()
f1
FigureWidget({ 'data': [], 'layout': {} })
Entering f1.add_<tab>
displays add methods for all of the supported trace types
#f1.add_scatter()
Entering f1.add_scatter(<tab>)
displays the names of all of the top-level properties for the scatter trace type
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
# f1.add_scatter(
f1.add_scatter(x=iris_df.sepal_length, y=iris_df.petal_width)
scatt1 = f1.data[0]
scatt1.mode = 'markers'
# That's not what we wanted, change the mode to 'markers'
scatt1.mode = 'markers'
# Set size to 8
scatt1.marker.size = 12
#scatt1.marker.size = -1
scatt1.marker.color = 'green'
# f1.layout.hovermode = 'nearest'
scatt1.marker.color = iris_class
# Change colorscale
scatt1.marker.cmin = 0.5
scatt1.marker.cmax = 3.5
scatt1.marker.colorscale = [[0, 'red'], [0.33, 'red'],
[0.33, 'green'], [0.67, 'green'],
[0.67, 'blue'], [1.0, 'blue']]
scatt1.marker.showscale = True
# Fix up colorscale ticks
scatt1.marker.colorbar.ticks = 'outside'
scatt1.marker.colorbar.tickvals = [1, 2, 3]
scatt1.marker.colorbar.ticktext = iris_data.target_names.tolist()
# Set colorscale title
scatt1.marker.colorbar.title = 'Species'
scatt1.marker.colorbar.titlefont.size = 16
scatt1.marker.colorbar.titlefont.family = 'Rockwell'
# Add axis labels
f1.layout.xaxis.title = 'sepal_length'
f1.layout.yaxis.title = 'petal_width'
# Hover info
scatt1.text = iris_data.target_names[iris_data.target]
scatt1.hoverinfo = 'text+x+y'
f1.layout.hovermode = 'closest'
# Set marker size based on petal_length
with f1.batch_animate(duration=1000):
scatt1.marker.size = np.sqrt(iris_df.petal_length.values * 50)
# Restore constant marker size
with f1.batch_animate(duration=1000):
scatt1.marker.size = 8
scatt1.marker.colorbar = None
scatt1.marker.colorscale = [[0, 'lightgray'], [0.5, 'lightgray'], [0.5, 'red'], [1, 'red']]
scatt1.marker.cmin = -0.5
scatt1.marker.cmax = 1.5
scatt1.marker.colorbar.ticks = 'outside'
scatt1.marker.colorbar.tickvals = [0, 1]
scatt1.marker.colorbar.ticktext = ['unselected', 'selected']
# Reset colors to zeros (unselected)
scatt1.marker.color = np.zeros(iris_class.size)
selected = np.zeros(iris_class.size)
# Assigning these variables here is not required. But doing so tricks Jupyter into
# providing property tab completion on the parameters to the brush function below
from plotly.callbacks import Points
trace, points = scatt1, Points()
def brush(trace, points, selector):
inds = np.array(points.point_inds)
if inds.size:
selected[inds] = 1
trace.marker.color = selected
scatt1.on_selection(brush)
Now box or lasso select points on the figure and see them turn red
# Reset brush
selected = np.zeros(iris_class.size)
scatt1.marker.color = selected
f2 = go.FigureWidget(data=[
go.Scatter(x=iris_df.petal_length, y=iris_df.sepal_width, mode='markers')])
f2
FigureWidget({ 'data': [{'mode': 'markers', 'type': 'scatter', 'uid': '940ad93…
# Set axis titles
f2.layout.xaxis.title = 'petal_length'
f2.layout.yaxis.title = 'sepal_width'
# Grab trace reference
scatt2 = f2.data[0]
# Set marker styles / colorbars to match between figures
scatt2.marker = scatt1.marker
# Configure brush on both plots to update both plots
def brush(trace, points, state):
inds = np.array(points.point_inds)
if inds.size:
selected = scatt1.marker.color.copy()
selected[inds] = 1
scatt1.marker.color = selected
scatt2.marker.color = selected
scatt1.on_selection(brush)
scatt2.on_selection(brush)
# Reset brush
def reset_brush(btn):
selected = np.zeros(iris_class.size)
scatt1.marker.color = selected
scatt2.marker.color = selected
# ipywidgets
from ipywidgets import HBox, VBox, Button
# Create reset button
button = Button(description="clear")
button.on_click(reset_brush)
button
Button(description='clear', style=ButtonStyle())
# Hide colorbar for figure 1
scatt1.marker.showscale = False
# Set dragmode to lasso for both plots
f1.layout.dragmode = 'lasso'
f2.layout.dragmode = 'lasso'
# Display two figures and the reset button
f1.layout.width = 500
f2.layout.width = 500
VBox([HBox([f1, f2]), button])
VBox(children=(HBox(children=(FigureWidget({ 'data': [{'hoverinfo': 'text+x+y', 'marker': {'…