交互性和选择

Altair 的交互性和选择语法是其在现有绘图库中的独特功能之一。在本节中,我们将介绍各种可用的选择类型,并开始练习创建交互式图表和仪表板。

有三种基本类型的选择可用

  • 区间选择:alt.selection_interval()

  • 单点选择:alt.selection_single()

  • 多点选择:alt.selection_multi()

我们将介绍四种可以使用这些选择进行的基本操作

  • 条件编码

  • 刻度

  • 过滤

import altair as alt
from vega_datasets import data

基本交互:平移、缩放、工具提示

Altair 提供的基本交互包括平移、缩放和工具提示。这可以在图表中完成,无需使用选择接口,只需使用 interactive() 快捷方法和 tooltip 编码。

例如,使用我们的标准汽车数据集,我们可以执行以下操作

cars = data.cars()
cars.head()
名称 每加仑英里数 气缸数 排量 马力 重量(磅) 加速度 年份 产地
0 chevrolet chevelle malibu 18.0 8 307.0 130.0 3504 12.0 1970-01-01 USA
1 buick skylark 320 15.0 8 350.0 165.0 3693 11.5 1970-01-01 USA
2 plymouth satellite 18.0 8 318.0 150.0 3436 11.0 1970-01-01 USA
3 amc rebel sst 16.0 8 304.0 150.0 3433 12.0 1970-01-01 USA
4 ford torino 17.0 8 302.0 140.0 3449 10.5 1970-01-01 USA
alt.Chart(cars).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color='Origin',
    tooltip='Name'
).interactive()

此时,将鼠标悬停在点上会显示一个工具提示,其中包含汽车型号的名称,点击/拖动/滚动将平移和缩放图表。

更复杂的交互:选择

基本选择示例:区间

作为一个选择的例子,让我们向图表添加一个区间选择。

我们将从我们的典型散点图开始

cars = data.cars()
cars.head()
名称 每加仑英里数 气缸数 排量 马力 重量(磅) 加速度 年份 产地
0 chevrolet chevelle malibu 18.0 8 307.0 130.0 3504 12.0 1970-01-01 USA
1 buick skylark 320 15.0 8 350.0 165.0 3693 11.5 1970-01-01 USA
2 plymouth satellite 18.0 8 318.0 150.0 3436 11.0 1970-01-01 USA
3 amc rebel sst 16.0 8 304.0 150.0 3433 12.0 1970-01-01 USA
4 ford torino 17.0 8 302.0 140.0 3449 10.5 1970-01-01 USA
alt.Chart(cars).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color='Origin'
)

要向图表添加选择行为,我们创建选择对象并使用 add_selection 方法

interval = alt.selection_interval()

alt.Chart(cars).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color='Origin'
).add_selection(
    interval
)

这为图表添加了一个交互,允许我们在图表上选择点;也许最常见的选择用途是根据选择结果来条件性地突出显示点(例如改变颜色)。

这可以使用 alt.condition 完成

interval = alt.selection_interval()

alt.Chart(cars).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color=alt.condition(interval, 'Origin', alt.value('lightgray'))
).add_selection(
    interval
)

alt.condition 函数接受三个参数:一个选择对象,应用于选择范围内的点的值,以及应用于选择范围外的点的值。这里我们使用 alt.value('lightgray') 来确保颜色被视为实际颜色,而不是数据列的名称。

定制区间选择

alt.selection_interval() 函数接受许多额外参数;例如,通过指定 encodings,我们可以控制选择是覆盖 x、y 还是两者

interval = alt.selection_interval(encodings=['x'])

alt.Chart(cars).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color=alt.condition(interval, 'Origin', alt.value('lightgray'))
).add_selection(
    interval
)
interval = alt.selection_interval(encodings=['y'])

alt.Chart(cars).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color=alt.condition(interval, 'Origin', alt.value('lightgray'))
).add_selection(
    interval
)

empty 参数让我们控制空选择是包含 所有 值还是 值;使用 empty='none' 时,点默认显示为灰色

interval = alt.selection_interval(empty='none')

alt.Chart(cars).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color=alt.condition(interval, 'Origin', alt.value('lightgray'))
).add_selection(
    interval
)

单点选择

alt.selection_single() 函数允许用户点击单个图表对象以一次选择一个。我们会将点放大一点,以便更容易点击

single = alt.selection_single()

alt.Chart(cars).mark_circle(size=100).encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color=alt.condition(single, 'Origin', alt.value('lightgray'))
).add_selection(
    single
)

单点选择也允许其他行为;例如,我们可以设置 nearest=Trueon='mouseover',以便在移动鼠标时将高亮更新到最近的点

single = alt.selection_single(on='mouseover', nearest=True)

alt.Chart(cars).mark_circle(size=100).encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color=alt.condition(single, 'Origin', alt.value('lightgray'))
).add_selection(
    single
)

多点选择

alt.selection_multi() 函数与 single 函数非常相似,不同之处在于它允许同时选择多个点,同时按住 Shift 键

multi = alt.selection_multi()

alt.Chart(cars).mark_circle(size=100).encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color=alt.condition(multi, 'Origin', alt.value('lightgray'))
).add_selection(
    multi
)

诸如 onnearest 之类的选项也适用于多点选择

multi = alt.selection_multi(on='mouseover', nearest=True)

alt.Chart(cars).mark_circle(size=100).encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color=alt.condition(multi, 'Origin', alt.value('lightgray'))
).add_selection(
    multi
)

选择绑定

上面我们看到了如何使用 alt.condition 将选择绑定到图表的不同方面。让我们看看选择的其他一些用法

绑定刻度

对于区间选择,您可以使用选择做的另一件事是将选择区域绑定到图表刻度

bind = alt.selection_interval(bind='scales')

alt.Chart(cars).mark_circle(size=100).encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color='Origin:N'
).add_selection(
    bind
)

这本质上是 chart.interactive() 方法在底层所做的事情。

将刻度绑定到其他域

也可以将刻度绑定到其他域,这在创建时非常有用

weather = data.seattle_weather()
weather.head()
日期 降水量 最高温度 最低温度 风速 天气
0 2012-01-01 0.0 12.8 5.0 4.7 毛毛雨
1 2012-01-02 10.9 10.6 2.8 4.5
2 2012-01-03 0.8 11.7 7.2 2.3
3 2012-01-04 20.3 12.2 5.6 4.7
4 2012-01-05 1.3 8.9 2.8 6.1
base = alt.Chart(weather).mark_rule().encode(
    x='date:T',
    y='temp_min:Q',
    y2='temp_max:Q',
    color='weather:N'
)

base
chart = base.properties(
    width=800,
    height=300
)

view = chart.properties(
    width=800,
    height=50
)

chart & view

让我们在底部图表添加一个区间选择,该选择将控制顶部图表的域

interval = alt.selection_interval(encodings=['x'])

base = alt.Chart(weather).mark_rule(size=2).encode(
    x='date:T',
    y='temp_min:Q',
    y2='temp_max:Q',
    color='weather:N'
)

chart = base.encode(
    x=alt.X('date:T', scale=alt.Scale(domain=interval.ref()))
).properties(
    width=800,
    height=300
)

view = base.add_selection(
    interval
).properties(
    width=800,
    height=50,
)

chart & view

按选择过滤

在多面板图表中,我们可以使用选择的结果来过滤数据的其他视图。例如,这是一个散点图以及一个直方图

interval = alt.selection_interval()

scatter = alt.Chart(cars).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color=alt.condition(interval, 'Origin:N', alt.value('lightgray'))
).add_selection(
    interval
)

hist = alt.Chart(cars).mark_bar().encode(
    x='count()',
    y='Origin',
    color='Origin'
).transform_filter(
    interval
)

scatter & hist

类似地,您可以使用多点选择以另一种方式(允许点击条形图来过滤散点图的内容)。我们将此添加到上一个图表中

click = alt.selection_multi(encodings=['color'])

scatter = alt.Chart(cars).mark_point().encode(
    x='Horsepower:Q',
    y='Miles_per_Gallon:Q',
    color='Origin:N'
).transform_filter(
    click
)

hist = alt.Chart(cars).mark_bar().encode(
    x='count()',
    y='Origin',
    color=alt.condition(click, 'Origin', alt.value('lightgray'))
).add_selection(
    click
)

scatter & hist

选择总结

  • 选择类型

    • selection_interval()

    • selection_single()

    • selection_multi()

  • 绑定

    • 绑定刻度:拖动和滚动以与图表交互

    • 绑定另一个图表上的刻度

    • 条件编码(例如颜色、大小)

    • 过滤数据

练习:选择

您可以在这里亲自尝试!选择以下一个或多个交互式示例进行创建

  1. 使用汽车数据集,创建一个散点图,其中点 大小 在您将鼠标悬停在其上时变大。

  2. 使用汽车数据集,创建一个双面板直方图(例如,一个面板显示每加仑英里数计数,另一个面板显示马力计数),您可以在其中拖动鼠标以选择左侧面板中的数据来过滤第二个面板中的数据。

  3. 修改我们上面进行的散点图加直方图示例,以便

    • 您可以在散点图上平移和缩放

    • 直方图仅反映 当前可见 的点

  4. 尝试新的东西!