Reputation: 1215
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)
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
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)
Upvotes: 2