Nicholas Vadivelu
Nicholas Vadivelu

Reputation: 61

Use interval_selection from one dataset/chart to filter data in another dataset/chart

I have two dataframes with seperate data that cannot be joined. I would like to create two charts, and use an interval_selection on one to filter data-points in the other. Below is my attempt to do so:

import altair as alt
import pandas as pd 

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

df = pd.DataFrame({
    'date': pd.to_datetime(['2022-01-03', '2022-01-04', '2022-01-04', '2022-01-05', '2022-01-06']),
    'x_value': [1., 2., 4., 3., 5.],
    'y_value': [4., 3., 2., 5., 1.],
})
other_data = pd.DataFrame({'date_col': pd.to_datetime([f'2022-01-0{i}' for i in range(1, 10)])})

scatter = alt.Chart(df).mark_point().encode(
    x='x_value:Q',
    y='y_value:Q',
).transform_filter(
    (alt.datum.date >= brush.x[0]) & (alt.datum.date <= brush.x[1])  # does not work
)

scatter2 = alt.Chart(other_data).mark_point().encode(x='date_col:T').add_selection(brush)

scatter & scatter2

Ideally, the code above should allow me to filter data pointers in scatter based on the date-range selected in scatter2. However, this plot does not render at all (the problematic line is indicated via a comment). How do I fix this? Thanks in advance!

Upvotes: 1

Views: 236

Answers (1)

joelostblom
joelostblom

Reputation: 48974

To filter on a brush, you don't need to make a comparison; it will be treated as a mask when passed to transform_filter.

You also need the same column name that is on the x-axis in the selection chart to be present as some type of encoding in the other chart as well. You can use detail if you don't want it to be mapped to a visual attribute (I also added shape below for clarity).

import altair as alt
import pandas as pd 


df = pd.DataFrame({
    'date': pd.to_datetime(['2022-01-03', '2022-01-04', '2022-01-04', '2022-01-05', '2022-01-06']),
    'x_value': [1., 2., 4., 3., 5.],
    'y_value': [4., 3., 2., 5., 1.],
})
other_data = pd.DataFrame({'date': pd.to_datetime([f'2022-01-0{i}' for i in range(1, 10)])})


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

scatter = alt.Chart(df).mark_point(size=200, filled=True).encode(
    x='x_value:Q',
    y='y_value:Q',
    shape='date(date):N',
    detail='date'
).transform_filter(
    brush
)

scatter2 = alt.Chart(other_data).mark_point().encode(x='date').add_selection(brush)

scatter & scatter2

enter image description here

Upvotes: 1

Related Questions