Selektoren#

bqplot.interacts bietet die folgenden Selektoren:

Klasse

Beschreibung

BrushIntervalSelector(**kwargs)

Auswahl eines Intervalls mit dem Pinsel

BrushSelector(**kwargs)

Auswahl mit dem Pinsel

HandDraw(**kwargs)

Handgezeichnete Interaktion

IndexSelector(**kwargs)

Auswahl eines Index

FastIntervalSelector(**kwargs)

Schnelle Auswahl eines Intervalls

MultiSelector(**kwargs)

Multiselektor-Interaktion

OneDSelector(**kwargs)

Eindimensionale Auswahl

Interaction(**kwargs)

Basisklasse für Interaktionen

PanZoom(**kwargs)

Interaktionen zum Verschieben und Zoomen von Skalen

Selector(**kwargs)

Auswahlinteraktion

TwoDSelector(**kwargs)

Zweidimensionale Auswahlinteraktion

[1]:
import numpy as np
import pandas as pd


symbol = "Security 1"
symbol2 = "Security 2"
[2]:
price_data = pd.DataFrame(
    np.cumsum(np.random.randn(150, 2).dot([[0.5, 0.4], [0.4, 1.0]]), axis=0)
    + 100,
    columns=["Security 1", "Security 2"],
    index=pd.date_range(start="01-01-2007", periods=150),
)

dates_actual = price_data.index.values
prices = price_data[symbol].values
[3]:
from bqplot import (
    Axis,
    Bars,
    DateScale,
    Figure,
    Hist,
    LinearScale,
    Lines,
    Scatter,
)
from bqplot.interacts import (
    BrushIntervalSelector,
    BrushSelector,
    FastIntervalSelector,
    HandDraw,
    IndexSelector,
    LassoSelector,
    MultiSelector,
    PanZoom,
)
from ipywidgets import HTML, ToggleButtons, VBox
from traitlets import link

Liniendiagramm-Selektoren#

FastIntervalSelector#

[4]:
## First we define a Figure
dt_x_fast = DateScale()
lin_y = LinearScale()

x_ax = Axis(label="Index", scale=dt_x_fast)
x_ay = Axis(label=(symbol + " Price"), scale=lin_y, orientation="vertical")
lc = Lines(
    x=dates_actual,
    y=prices,
    scales={"x": dt_x_fast, "y": lin_y},
    colors=["orange"],
)
lc_2 = Lines(
    x=dates_actual[50:],
    y=prices[50:] + 2,
    scales={"x": dt_x_fast, "y": lin_y},
    colors=["blue"],
)
[5]:
## Next we define the type of selector we would like
intsel_fast = FastIntervalSelector(scale=dt_x_fast, marks=[lc, lc_2])
[6]:
## Now, we define a function that will be called when the FastIntervalSelector is interacted with
def fast_interval_change_callback(change):
    db_fast.value = "The selected period is " + str(change.new)
[7]:
## Now we connect the selectors to that function
intsel_fast.observe(fast_interval_change_callback, names=["selected"])
[8]:
## We use the HTML widget to see the value of what we are selecting and modify it when an interaction is performed
## on the selector
db_fast = HTML()
db_fast.value = "The selected period is " + str(intsel_fast.selected)

fig_fast_intsel = Figure(
    marks=[lc, lc_2],
    axes=[x_ax, x_ay],
    title="Fast Interval Selector Example",
    interaction=intsel_fast,
)  # This is where we assign the interaction to this particular Figure

VBox([db_fast, fig_fast_intsel])

IndexSelector#

[9]:
db_index = HTML(value="[]")
[10]:
## Now we try a selector made to select all the y-values associated with a single x-value
index_sel = IndexSelector(scale=dt_x_fast, marks=[lc, lc_2])
[11]:
## Now, we define a function that will be called when the selectors are interacted with
def index_change_callback(change):
    db_index.value = "The selected date is " + str(change.new)
[12]:
index_sel.observe(index_change_callback, names=["selected"])
[13]:
fig_index_sel = Figure(
    marks=[lc, lc_2],
    axes=[x_ax, x_ay],
    title="Index Selector Example",
    interaction=index_sel,
)
VBox([db_index, fig_index_sel])

Rückgabe von Indizes ausgewählter Werte:

[14]:
from datetime import datetime as py_dtime


dt_x_index = DateScale(min=np.datetime64(py_dtime(2006, 6, 1)))
lin_y2 = LinearScale()

lc2_index = Lines(
    x=dates_actual, y=prices, scales={"x": dt_x_index, "y": lin_y2}
)

x_ax1 = Axis(label="Date", scale=dt_x_index)
x_ay2 = Axis(label=(symbol + " Price"), scale=lin_y2, orientation="vertical")
[15]:
intsel_date = FastIntervalSelector(scale=dt_x_index, marks=[lc2_index])
[16]:
db_date = HTML()
db_date.value = str(intsel_date.selected)
[17]:
## Now, we define a function that will be called when the selectors are interacted with - a callback
def date_interval_change_callback(change):
    db_date.value = str(change.new)
[18]:
## Notice here that we call the observe on the Mark lc2_index rather than on the selector intsel_date
lc2_index.observe(date_interval_change_callback, names=["selected"])

fig_date_mark = Figure(
    marks=[lc2_index],
    axes=[x_ax1, x_ay2],
    title="Fast Interval Selector Selected Indices Example",
    interaction=intsel_date,
)

VBox([db_date, fig_date_mark])

BrushSelector#

Wir können dasselbe mit jedem anderen Selektor tun:

[19]:
## Defining a new Figure
dt_x_brush = DateScale(min=np.datetime64(py_dtime(2006, 6, 1)))
lin_y2_brush = LinearScale()

lc3_brush = Lines(
    x=dates_actual, y=prices, scales={"x": dt_x_brush, "y": lin_y2_brush}
)

x_ax_brush = Axis(label="Date", scale=dt_x_brush)
x_ay_brush = Axis(
    label=(symbol + " Price"), scale=lin_y2_brush, orientation="vertical"
)
[20]:
db_brush = HTML(value="[]")
[21]:
brushsel_date = BrushIntervalSelector(
    scale=dt_x_brush, marks=[lc3_brush], color="FireBrick"
)
[22]:
## Now, we define a function that will be called when the selectors are interacted with - a callback
def date_brush_change_callback(change):
    db_brush.value = str(change.new)
[23]:
lc3_brush.observe(date_brush_change_callback, names=["selected"])
[24]:
fig_brush_sel = Figure(
    marks=[lc3_brush],
    axes=[x_ax_brush, x_ay_brush],
    title="Brush Selector Selected Indices Example",
    interaction=brushsel_date,
)

VBox([db_brush, fig_brush_sel])

Scatter-Chart-Selektoren#

BrushSelector#

[25]:
date_fmt = "%m-%d-%Y"

sec2_data = price_data[symbol2].values
dates = price_data.index.values
[26]:
sc_x = LinearScale()
sc_y = LinearScale()

scatt = Scatter(x=prices, y=sec2_data, scales={"x": sc_x, "y": sc_y})

sc_xax = Axis(label=(symbol), scale=sc_x)
sc_yax = Axis(label=(symbol2), scale=sc_y, orientation="vertical")
[27]:
br_sel = BrushSelector(x_scale=sc_x, y_scale=sc_y, marks=[scatt], color="red")

db_scat_brush = HTML(value="[]")
[28]:
## call back for the selector
def brush_callback(change):
    db_scat_brush.value = str(br_sel.selected)
[29]:
br_sel.observe(brush_callback, names=["brushing"])
[30]:
fig_scat_brush = Figure(
    marks=[scatt],
    axes=[sc_xax, sc_yax],
    title="Scatter Chart Brush Selector Example",
    interaction=br_sel,
)
[31]:
VBox([db_scat_brush, fig_scat_brush])

BrushSelector mit Datumswerten#

[32]:
sc_brush_dt_x = DateScale(date_format=date_fmt)
sc_brush_dt_y = LinearScale()

scatt2 = Scatter(
    x=dates_actual,
    y=sec2_data,
    scales={"x": sc_brush_dt_x, "y": sc_brush_dt_y},
)
[33]:
br_sel_dt = BrushSelector(
    x_scale=sc_brush_dt_x, y_scale=sc_brush_dt_y, marks=[scatt2]
)
[34]:
db_brush_dt = HTML(value=str(br_sel_dt.selected))
[35]:
## call back for the selector
def brush_dt_callback(change):
    db_brush_dt.value = str(br_sel_dt.selected)
[36]:
br_sel_dt.observe(brush_dt_callback, names=["brushing"])
[37]:
sc_xax = Axis(label=(symbol), scale=sc_brush_dt_x)
sc_yax = Axis(label=(symbol2), scale=sc_brush_dt_y, orientation="vertical")
fig_brush_dt = Figure(
    marks=[scatt2],
    axes=[sc_xax, sc_yax],
    title="Brush Selector with Dates Example",
    interaction=br_sel_dt,
)
[38]:
VBox([db_brush_dt, fig_brush_dt])

Histogramm-Selektoren#

[39]:
## call back for selectors
def interval_change_callback(name, value):
    db3.value = str(value)


## call back for the selector
def brush_callback(change):
    if not br_intsel.brushing:
        db3.value = str(br_intsel.selected)
[40]:
returns = np.log(prices[1:]) - np.log(prices[:-1])
hist_x = LinearScale()
hist_y = LinearScale()
hist = Hist(sample=returns, scales={"sample": hist_x, "count": hist_y})

br_intsel = BrushIntervalSelector(scale=hist_x, marks=[hist])
br_intsel.observe(brush_callback, names=["selected"])
br_intsel.observe(brush_callback, names=["brushing"])

db3 = HTML()
db3.value = str(br_intsel.selected)

h_xax = Axis(
    scale=hist_x,
    label="Returns",
    grids="off",
    set_ticks=True,
    tick_format="0.2%",
)
h_yax = Axis(
    scale=hist_y, label="Freq", orientation="vertical", grid_lines="none"
)

fig_hist = Figure(
    marks=[hist],
    axes=[h_xax, h_yax],
    title="Histogram Selection Example",
    interaction=br_intsel,
)
VBox([db3, fig_hist])

MultiSelector#

  • Dieser Selektor bietet die Möglichkeit, mehrere Pinsel-Selektoren in einem Diagramm zu verwenden.

  • Der erste Pinsel funktioniert wie ein normaler Pinsel.

  • Ctrl + click erstellt einen neuen Pinsel, der wie der normale Pinsel funktioniert.

  • Der active-Pinsel hat einen grünen Rand, während alle inactive-Pinsel einen roten Rand haben. inactive

  • Shift + click deaktiviert den aktuellen active-Pinsel. Klickt nun auf einen inactive-Pinsel um ihn active zu machen.

  • Ctrl + Alt + Shift + click löscht alle Pinsel und setzt sie zurück.

[41]:
def multi_sel_callback(change):
    if not multi_sel.brushing:
        db4.value = str(multi_sel.selected)
[42]:
line_x = LinearScale()
line_y = LinearScale()
line = Lines(
    x=np.arange(100), y=np.random.randn(100), scales={"x": line_x, "y": line_y}
)

multi_sel = MultiSelector(scale=line_x, marks=[line])
multi_sel.observe(multi_sel_callback, names=["selected"])
multi_sel.observe(multi_sel_callback, names=["brushing"])

db4 = HTML()
db4.value = str(multi_sel.selected)

h_xax = Axis(scale=line_x, label="Returns", grid_lines="none")
h_yax = Axis(
    scale=hist_y, label="Freq", orientation="vertical", grid_lines="none"
)

fig_multi = Figure(
    marks=[line],
    axes=[h_xax, h_yax],
    title="Multi-Selector Example",
    interaction=multi_sel,
)
VBox([db4, fig_multi])
[43]:
# changing the names of the intervals.
multi_sel.names = ["int1", "int2", "int3"]

Multifunktionswähler mit Datum#

[44]:
def multi_sel_dt_callback(change):
    if not multi_sel_dt.brushing:
        db_multi_dt.value = str(multi_sel_dt.selected)
[45]:
line_dt_x = DateScale(min=np.datetime64(py_dtime(2007, 1, 1)))
line_dt_y = LinearScale()
line_dt = Lines(
    x=dates_actual,
    y=sec2_data,
    scales={"x": line_dt_x, "y": line_dt_y},
    colors=["red"],
)

multi_sel_dt = MultiSelector(scale=line_dt_x)
multi_sel_dt.observe(multi_sel_dt_callback, names=["selected"])
multi_sel_dt.observe(multi_sel_dt_callback, names=["brushing"])

db_multi_dt = HTML()
db_multi_dt.value = str(multi_sel_dt.selected)

h_xax_dt = Axis(scale=line_dt_x, label="Returns", grid_lines="none")
h_yax_dt = Axis(
    scale=line_dt_y, label="Freq", orientation="vertical", grid_lines="none"
)

fig_multi_dt = Figure(
    marks=[line_dt],
    axes=[h_xax_dt, h_yax_dt],
    title="Multi-Selector with Date Example",
    interaction=multi_sel_dt,
)
VBox([db_multi_dt, fig_multi_dt])

LassoSelector#

[46]:
lasso_sel = LassoSelector()
[47]:
xs, ys = LinearScale(), LinearScale()
data = np.arange(20)
line_lasso = Lines(x=data, y=data, scales={"x": xs, "y": ys})
scatter_lasso = Scatter(
    x=data, y=data, scales={"x": xs, "y": ys}, colors=["skyblue"]
)
bar_lasso = Bars(x=data, y=data / 2.0, scales={"x": xs, "y": ys})
xax_lasso, yax_lasso = Axis(scale=xs, label="X"), Axis(
    scale=ys, label="Y", orientation="vertical"
)
fig_lasso = Figure(
    marks=[scatter_lasso, line_lasso, bar_lasso],
    axes=[xax_lasso, yax_lasso],
    title="Lasso Selector Example",
    interaction=lasso_sel,
)
lasso_sel.marks = [scatter_lasso, line_lasso]
fig_lasso
[48]:
scatter_lasso.selected, line_lasso.selected
[48]:
(None, None)

PanZoom#

[49]:
xs_pz = DateScale(min=np.datetime64(py_dtime(2007, 1, 1)))
ys_pz = LinearScale()
line_pz = Lines(
    x=dates_actual,
    y=sec2_data,
    scales={"x": xs_pz, "y": ys_pz},
    colors=["red"],
)

panzoom = PanZoom(scales={"x": [xs_pz], "y": [ys_pz]})
xax = Axis(scale=xs_pz, label="Date", grids="off")
yax = Axis(
    scale=ys_pz, label="Price", orientation="vertical", grid_lines="none"
)

Figure(marks=[line_pz], axes=[xax, yax], interaction=panzoom)

HandDraw#

[50]:
xs_hd = DateScale(min=np.datetime64(py_dtime(2007, 1, 1)))
ys_hd = LinearScale()
line_hd = Lines(
    x=dates_actual,
    y=sec2_data,
    scales={"x": xs_hd, "y": ys_hd},
    colors=["red"],
)

handdraw = HandDraw(lines=line_hd)
xax = Axis(scale=xs_hd, label="Date", grid_lines="none")
yax = Axis(
    scale=ys_hd, label="Price", orientation="vertical", grid_lines="none"
)

Figure(marks=[line_hd], axes=[xax, yax], interaction=handdraw)

Figure mit allen Interaktionen#

Figure definieren:

[51]:
dt_x = DateScale(date_format=date_fmt, min=py_dtime(2007, 1, 1))
lc1_x = LinearScale()
lc2_y = LinearScale()

lc2 = Lines(
    x=np.linspace(0.0, 10.0, len(prices)),
    y=prices * 0.25,
    scales={"x": lc1_x, "y": lc2_y},
    display_legend=True,
    labels=["Security 1"],
)

lc3 = Lines(
    x=dates_actual,
    y=sec2_data,
    scales={"x": dt_x, "y": lc2_y},
    colors=["red"],
    display_legend=True,
    labels=["Security 2"],
)

lc4 = Lines(
    x=np.linspace(0.0, 10.0, len(prices)),
    y=sec2_data * 0.75,
    scales={"x": LinearScale(min=5, max=10), "y": lc2_y},
    colors=["green"],
    display_legend=True,
    labels=["Security 2 squared"],
)

x_ax1 = Axis(label="Date", scale=dt_x)
x_ax2 = Axis(label="Time", scale=lc1_x, side="top", grid_lines="none")
x_ay2 = Axis(label=(symbol + " Price"), scale=lc2_y, orientation="vertical")


fig = Figure(marks=[lc2, lc3, lc4], axes=[x_ax1, x_ax2, x_ay2])

Interaktionen definieren:

[52]:
multi_sel = MultiSelector(scale=dt_x, marks=[lc2, lc3])
br_intsel = BrushIntervalSelector(scale=lc1_x, marks=[lc2, lc3])
index_sel = IndexSelector(scale=dt_x, marks=[lc2, lc3])
int_sel = FastIntervalSelector(scale=dt_x, marks=[lc3, lc2])

hd = HandDraw(lines=lc2)
hd2 = HandDraw(lines=lc3)
pz = PanZoom(scales={"x": [dt_x], "y": [lc2_y]})

deb = HTML()
deb.value = "[]"

Call-Back-Handler für die Interaktionen definieren:

[53]:
def test_callback(change):
    deb.value = str(change.new)


multi_sel.observe(test_callback, names=["selected"])
br_intsel.observe(test_callback, names=["selected"])
index_sel.observe(test_callback, names=["selected"])
int_sel.observe(test_callback, names=["selected"])
[54]:
from collections import OrderedDict


selection_interacts = ToggleButtons(
    options=OrderedDict(
        [
            ("HandDraw1", hd),
            ("HandDraw2", hd2),
            ("PanZoom", pz),
            ("FastIntervalSelector", int_sel),
            ("IndexSelector", index_sel),
            ("BrushIntervalSelector", br_intsel),
            ("MultiSelector", multi_sel),
            ("None", None),
        ]
    )
)

link((selection_interacts, "value"), (fig, "interaction"))
VBox([deb, fig, selection_interacts], align_self="stretch")