Dan
Dan

Reputation: 45

How to click on square of heatmap to filter linked bar chart? (altair)

I'm trying to get it so if I click on a square of a heatmap, a neighboring bar chart shows additional info on the data represented in that square (also the heatmap square should "light up" when clicked on). The code below gets the heatmap working the way I want, but I don't understand why the barchart isn't working.

(Also, if I do interval = alt.selection_single(encodings=['x','y'] instead, the barchart starts doing what I want it to, but then the heatmap stops working.)

import altair as alt
from vega_datasets import data
cars = data.cars()

interval = alt.selection_single()

chart = alt.Chart(cars).mark_bar().encode(
    x=alt.X('Miles_per_Gallon', bin=True), 
    y=alt.X('Horsepower', bin=True),
    color=alt.condition(interval, 'count()', alt.value('lightgray'))
).properties(
    selection=interval
)

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

chart | hist

Screenshot

Upvotes: 3

Views: 665

Answers (1)

jakevdp
jakevdp

Reputation: 86433

When you want single or multi selections to apply across different data views, you need to specify the fields or encodings that the selection applies to, to tell the second chart what to trigger on. For example:

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

For some reason, though this is breaking the color condition – I think this is probably some bug in Vega-Lite related to selections & binning. You can work around that by using two selections, one for the highlight and one for the filter:

import altair as alt
from vega_datasets import data
cars = data.cars()

highlight = alt.selection_single()
select = alt.selection_single(encodings=['x', 'y'])

chart = alt.Chart(cars).mark_rect().encode(
    x=alt.X('Miles_per_Gallon', bin=True), 
    y=alt.X('Horsepower', bin=True),
    color=alt.condition(highlight, 'count()', alt.value('lightgray'))
).add_selection(
    highlight, select
)

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

chart | hist

enter image description here

Upvotes: 5

Related Questions