tl;dr: is there a way to get a dynamic count of points in filtered plots in Altair?
In the 'filtering by selection' example for Altair, it is possible to update a scatterplot based on a selection in a linked bar chart.
import altair as alt
from vega_datasets import data
cars = data.cars()
click = alt.selection_point(encodings=['color'])
scatter = alt.Chart(cars).mark_point().encode(
x='Horsepower:Q',
y='Miles_per_Gallon:Q',
color='Origin:N'
).transform_filter(
click
)
hist = alt.Chart(cars).mark_bar().encode(
x='count()',
y='Origin',
color=alt.condition(click, 'Origin', alt.value('lightgray'))
).add_params(
click
)
scatter & hist
However, it would be useful to show how many data points remain in the scatterplot after filtering. How can this be achieved?
It is possible to get a static count of data in a dataframe and use that for a label, which I tried with another approach eg:
import altair as alt
import pandas as pd
# Sample data
data = pd.DataFrame({'values': [1, 2, 3, 4, 5, 1, 2, 3]})
total_count = data['values'].sum()
# Create data frame for total count
count_data = pd.DataFrame({'label': ['Total Count'], 'count': [total_count]})
# Combine data
combined_data = pd.concat([data, count_data])
# Create histogram with text for total count
hist = alt.Chart(combined_data).mark_bar().encode(
x='values:Q',
y='count()',
)
text = hist.mark_text(
color='black',
baseline='middle'
).encode(
x=alt.value(200), # Adjust position as needed
y=alt.value(40),
text='count:Q',
)
# Display the chart
hist + text
This adds a rather ugly label:
Is there a way to append a dynamic label with the number of points present in the filtered scatterplot? An external element would be fine, but I am quite new to Altair and haven't figured that bit out yet despite some searching.



To show a dynamic count of filtered data in Altair, use
transform_aggregateShowing how many data points are present on a plot after filtering can be done with a combination of
transform_aggregateto retrive acount, and text marks.The aggregate transformation can be added on to the the plot which is getting filtered, eg:
filtered_plot.transform_aggregate(count='count(*)'). The Text mark can then be applied as you would any label.Example using iris sepal data
Note: adding the text with count adds an 'undefined' field in the legend, which I have yet to find a way to remove
Code: