Thomas
Thomas

Reputation: 1215

Show selection box over multiple rows in Altair

I want to create a plot using altair that spans multiple rows and is interactive. Highlighting a subregion of the plot correctly highlights that region in all rows by changing the color outside that region to grey. Here's my MWE with a screenshot of the interactive plot that's generated:

import altair as alt
from vega_datasets import data

source = data.stocks()

brush = alt.selection_interval(encodings=["x"], mark=alt.BrushConfig(fill="green"))

histogram = (
    alt.Chart(source)
    .mark_bar()
    .encode(
        x="date:T",
        y="price:Q",
        color=alt.condition(brush, "symbol:N", alt.value("gray"), legend=None),
    )
)
   
overlay = (
    alt.Chart(source)
    .mark_rect(opacity=0.8)
    .encode(
        x="date:T",
        y="proce:Q",
        color=alt.condition(brush, alt.value("green"), alt.value("gray"), legend=None),
    )
)
(histogram + overlay).properties(height=50, width=400).facet(
    row=alt.Row("symbol:N",)
).transform_filter(alt.datum.symbol != "GOOG").add_selection(brush)

enter image description here

I selected a range in the first row and only that row has the green background that I tried to add to every row (via the overlay). Clearly I failed. Is there a way to have the green selection box on all rows, regardless of which row I select the range from?

Upvotes: 1

Views: 335

Answers (1)

joelostblom
joelostblom

Reputation: 48974

It is not possible to show a selection on multiple charts https://github.com/vega/vega-lite/issues/3686, https://github.com/vega/vega-lite/issues/7030, vega-lite: synchron selection in multiple chart.

Building on your approach, you could do something like this (can't figure out how to remove the spacing/padding between the bars in the overlay, might be an issue with temporal scales or strokes):

import altair as alt
from vega_datasets import data

source = data.stocks()

brush = alt.selection_interval(encodings=["x"], mark=alt.BrushConfig(fill='w'), empty='none')

histogram = (
    alt.Chart(source)
    .mark_bar()
    .encode(
        x="date:T",
        y="price:Q",
        color=alt.condition(brush, "symbol:N", alt.value("gray"), legend=None),
    )
)
   
overlay = (
    alt.Chart(source)
    .mark_bar(color='green')
    .encode(
        x=alt.X('date:T', scale=alt.Scale(paddingInner=0)),
        y=alt.datum(250),
        opacity=alt.condition(brush, alt.value(0.1), alt.value(0), legend=None),
    )
)
(histogram + overlay).properties(height=50, width=400).facet(
    row=alt.Row("symbol:N",)
).transform_filter(alt.datum.symbol != "GOOG").add_selection(brush)

enter image description here

Upvotes: 2

Related Questions