交互式地块选择不会突出亮点

时间:2018-09-09 00:20:04

标签: python interactive vega-lite altair

我正在尝试在Altair中生成两个共享相同selection的地块。

我想绘制人口(y)与年龄(x)的散点图和条形图。我正在使用Altair内置数据集population。总体是此数据集中people列的总和。数据集包含yearpeopleagesex的列。我可以使用sum(people)获得总数,并将其绘制成yage。对于条形图,我可以使用sum(people)列类似地绘制sex与年龄和颜色的关系。

我正在尝试在这2个图之间设置笔刷/选择,以便可以在散布图中突出显示,同时更新条形图以反映该选择。但是,我遇到了以下问题

我使用Altair文档中的layered bar graph example作为示例。

这是代码

import altair as alt
from altair.expr import datum, if_
from vega_datasets import data
interval = alt.selection_interval(encodings=['x', 'y'])

df = data.population.url

scatter = alt.Chart(df).mark_point().encode(
    alt.X('age:O', axis=alt.Axis(title='')),
    y='sum(people)',
    color=alt.condition(interval, 'sex:N', alt.value('lightgrey'))
).transform_filter(
    filter = datum.year == 2000
).transform_calculate(
    "sex", if_(datum.sex == 2, 'Female', 'Male')
).properties(
    selection=interval
)

bar = alt.Chart(df).mark_bar(opacity=0.7).encode(
    alt.X('age:O', scale=alt.Scale(rangeStep=17)),
    alt.Y('sum(people)', stack=None),
    color=alt.condition(interval, 'sex:N', alt.value('lightgrey')),
).transform_filter(
    filter = datum.year == 2000
).transform_calculate(
    "sex", if_(datum.sex == 2, 'Female', 'Male')
).properties(height=100, width=400)

scatter & bar

我已经修改了文档示例中的代码。我首先创建一个散点图,然后使用基于selection的颜色。然后,我定义了相同两列的条形图,并再次使用selection指定颜色。这是输出

enter image description here

现在,我想在顶部(散点)图上拖动一个框以选择一些点,同时底部(条形图)应基于selection更新。当我在最上面的情节中拖动以制作selection时,就会发生这种情况

enter image description here

问题

  1. 在顶部绘图中进行拖动以进行选择后,两个绘图中的颜色(内部和外部)均更改为lightgrey。我期望在两个图中,选中/画笔内部都应突出显示,但外部应为lightgrey

如何获得同时显示在顶部和底部图上的选择?

编辑

我想要this behaviour,其中在一个绘图中的笔刷/选择同时在第二个(链接的)绘图中突出显示。

打包版本:

Python = 3.6
Altair = 2.2
Jupyter = 5.6

2 个答案:

答案 0 :(得分:2)

要触发对合计值的选择,最好的方法是使用合计变换来定义该数量,以便整个图表均可使用。

这里是一个例子:

import altair as alt
from altair.expr import datum, if_
from vega_datasets import data

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


base = alt.Chart(data.population.url).transform_filter(
    filter = datum.year == 2000
).transform_calculate(
    "sex", if_(datum.sex == 2, 'Female', 'Male')
).transform_aggregate(
    population="sum(people)",
    groupby=['age', 'sex']
)

scatter = base.mark_point().encode(
    alt.X('age:O', title=''),
    y='population:Q',
    color=alt.condition(interval, 'sex:N', alt.value('lightgrey'))
).properties(
    selection=interval
)

bar = base.mark_bar(opacity=0.7).encode(
    alt.X('age:O', scale=alt.Scale(rangeStep=17)),
    alt.Y('population:Q'),
    color=alt.condition(interval, 'sex:N', alt.value('lightgrey')),
).properties(height=100, width=400)

scatter & bar

请注意,我通过下面图的间隔选择取消了过滤,因为这不是您描述的行为。

答案 1 :(得分:0)

基于(并调整)上面@jakevdp的答案,我尝试了类似于文档库“交互式图表”部分中的this example

我没有使用base对象,而是使用了vconcat函数,该函数加入了Chart实例并将转换和数据传递到vconcat对象。这是方法

import altair as alt
from altair.expr import datum, if_
from vega_datasets import data
interval = alt.selection_interval(encodings=['x', 'y'])

scatter = alt.Chart().mark_point().encode(
    alt.X('age:O', title=''),
    y='population:Q',
    color=alt.condition(interval, 'sex:N', alt.value('lightgrey'))
).properties(
    selection=interval
)

bar = alt.Chart().mark_bar(opacity=0.7).encode(
    alt.X('age:O', scale=alt.Scale(rangeStep=17)),
    alt.Y('population:Q'),
    color=alt.condition(interval, 'sex:N', alt.value('lightgrey')),
).properties(height=100, width=400)

alt.vconcat(scatter, bar,
    data=data.population.url
).transform_filter(
    filter = datum.year == 2000
).transform_calculate(
    "sex", if_(datum.sex == 2, 'Female', 'Male')
).transform_aggregate(
    population="sum(people)",
    groupby=['age', 'sex']
)

这种方法似乎具有与@jakevdp的答案相同的功能。可以对散点图(顶部)进行选择,并根据需要将其反映在条形图(底部)中。