In [ ]:
import pandas as pd
import numpy as np
symbol = 'Security 1'
symbol2 = 'Security 2'
In [ ]:
price_data = pd.DataFrame(np.cumsum(np.random.randn(150, 2).dot([[0.5, 0.4], [0.4, 1.0]]), axis=0) + 100,
columns=[symbol, symbol2],
index=pd.date_range(start='01-01-2007', periods=150))
dates_actual = price_data.index.values
prices = price_data[symbol].values
In [ ]:
from bqplot import *
from bqplot.interacts import (
FastIntervalSelector, IndexSelector, BrushIntervalSelector,
BrushSelector, MultiSelector, LassoSelector,
)
from ipywidgets import ToggleButtons, VBox, HTML
Selectors are part of the Interaction Layer (link). They are used to select subparts of Marks, that correspond to different regions on the Figure canvas. Different types of selectors select different types of regions:
BrushSelector
, FastIntervalSelector
and MultiSelector
select rectangular regionsIndexSelector
selects the elements closest to an abcissaLassoSelector
selects elements in a region drawn by the userbqplot Selectors need to be tied to two other widgets:
selected
attribute, a list of data indices, will be set by the Selector
instance.Scales
. These are the scales that the Selector
operates on. The Selector
's selected
attribute will be expressed as values of those scales.The Selector
must then be passed to the desired Figure
, as its interaction
attribute.
Hopefully this will be clear in the following examples.
In [ ]:
# Define scales for the rest of the notebook
scales = {'x': DateScale(), 'y': LinearScale()}
In [ ]:
# The Mark we want to select subsamples of
scatter = Scatter(x=dates_actual, y=prices, scales=scales, colors=['orange'],
selected_style={'opacity': '1'}, unselected_style={'opacity': '0.2'})
# Create the brush selector, passing it its corresponding scale.
# Notice that we do not pass it any marks for now
brushintsel = BrushIntervalSelector(scale=scales['x'])
x_ax = Axis(label='Index', scale=scales['x'])
x_ay = Axis(label=(symbol + ' Price'), scale=scales['y'], orientation='vertical')
# Pass the Selector instance to the Figure
fig = Figure(marks=[scatter], axes=[x_ax, x_ay],
title='''Brush Interval Selector Example. Click and drag on the Figure to action.''',
interaction=brushintsel)
# The following text widgets are used to display the `selected` attributes
text_brush = HTML()
text_scatter = HTML()
# This function updates the text, triggered by a change in the selector
def update_brush_text(*args):
text_brush.value = "The Brush's selected attribute is {}".format(brushintsel.selected)
def update_scatter_text(*args):
text_scatter.value = "The scatter's selected indices are {}".format(scatter.selected)
brushintsel.observe(update_brush_text, 'selected')
scatter.observe(update_scatter_text, 'selected')
update_brush_text()
update_scatter_text()
# Display
VBox([fig, text_brush, text_scatter])
In [ ]:
brushintsel.marks = [scatter]
From now on we will stop printing out the selected indices, but rather use the selected_style
and unselected_style
attributes of the Marks to check which elements are selected.
In [ ]:
def create_figure(selector, **selector_kwargs):
'''
Returns a Figure with a Scatter and a Selector.
Arguments
---------
selector: The type of Selector, one of
{'BrushIntervalSelector', 'BrushSelector', 'FastIntervalSelector', 'IndexSelector', 'LassoSelector'}
selector_kwargs: Arguments to be passed to the Selector
'''
scatter = Scatter(x=dates_actual, y=prices, scales=scales, colors=['orange'],
selected_style={'opacity': '1'}, unselected_style={'opacity': '0.2'})
sel = selector(marks=[scatter], **selector_kwargs)
text_brush = HTML()
if selector != LassoSelector:
def update_text(*args):
text_brush.value = '{}.selected = {}'.format(selector.__name__, sel.selected)
sel.observe(update_text, 'selected')
update_text()
x_ax = Axis(label='Index', scale=scales['x'])
x_ay = Axis(label=(symbol + ' Price'), scale=scales['y'], orientation='vertical')
fig = Figure(marks=[scatter], axes=[x_ax, x_ay], title='{} Example'.format(selector.__name__),
interaction=sel)
return VBox([fig, text_brush])
In [ ]:
create_figure(BrushIntervalSelector, orientation='vertical', scale=scales['y'])
In [ ]:
create_figure(BrushSelector, x_scale=scales['x'], y_scale=scales['y'])
The FastIntervalSelector is functionally like a BrushIntervalSelector, but provides a more fluid and rapid interaction.
Experiment and get a feel for it in the example below.
In [ ]:
create_figure(FastIntervalSelector, scale=scales['x'])
As of the latest version, FastIntervalSelector
is only supported for 1d interaction along the x-axis
In [ ]:
create_figure(LassoSelector)
In [ ]:
create_figure(IndexSelector, scale=scales['x'])
As of the latest version, IndexSelector
is only supported for interaction along the x-axis.
This 1-D selector is equivalent to multiple brush selectors.
Ctrl + click
creates a new brush, which works like the regular brush. active
brush has a Green border while all the inactive
brushes have a Red border.Shift + click
deactivates the current active
brush. Now, click on any inactive
brush to make it active
.Ctrl + Shift + click
clears and resets all the brushes.Each brush has a name (0, 1, 2, ... by default), and the selected
attribute is a dict {brush_name: brush_extent}
In [ ]:
create_figure(MultiSelector, scale=scales['x'])