如何在VConcatChart中实现交互式图表的水平比例尺联动?
Great question! When working with VConcatChart (vertical concatenation) in Altair, keeping the horizontal (x-axis) scale synchronized across multiple interactive charts is totally achievable. Below are two practical approaches tailored to different scenarios:
Approach 1: Shared X-Axis Scale + Global Interaction
This is the simplest method when all your subcharts use the same x-axis variable (or variables with matching ranges/types). By sharing the x-scale and adding a global interactive handler, any zoom/pan action on one chart will automatically update the others.
Example Code
import altair as alt from vega_datasets import data # Load sample data source = data.cars() # Create first interactive chart (scatter plot) scatter_plot = alt.Chart(source).mark_point().encode( x='Horsepower:Q', y='Miles_per_Gallon:Q' ) # Create second interactive chart (histogram) histogram = alt.Chart(source).mark_bar().encode( x='Horsepower:Q', y='count()' ) # Vertically concat charts, share x-scale, and enable global interaction alt.vconcat(scatter_plot, histogram).resolve_scale(x='shared').interactive()
How It Works
resolve_scale(x='shared')forces all subcharts to use a single x-axis scale instead of independent ones..interactive()adds default zoom (mouse wheel) and pan (drag) interactions to the entire concatenated chart. Any interaction on either subchart updates the shared scale, so all charts stay in sync.
Approach 2: Custom Selection for Fine-Grained Control
If your subcharts use different x-axis variables (but still need synchronized ranges) or you want to use a specific interaction like brush selection to sync scales, this method gives you more flexibility.
Example Code
import altair as alt from vega_datasets import data source = data.cars() # Define a shared x-axis interval selection (works across all charts) shared_x_brush = alt.selection_interval(encodings=['x'], name='synced_x') # First chart: Add the brush and bind x-scale to the selection chart1 = alt.Chart(source).mark_point().encode( x=alt.X('Horsepower:Q').scale(domain={'selection': shared_x_brush.name}), y='Miles_per_Gallon:Q' ).add_params(shared_x_brush) # Second chart: Bind its x-scale to the same shared selection chart2 = alt.Chart(source).mark_line().encode( x=alt.X('Horsepower:Q').scale(domain={'selection': shared_x_brush.name}), y='Acceleration:Q' ) # Vertically concatenate the charts alt.vconcat(chart1, chart2)
How It Works
shared_x_brushcreates a reusable interval selection that targets the x-axis.- By setting
scale(domain={'selection': shared_x_brush.name})on each chart's x-axis, we force their scales to match the range of the brush selection. Dragging the brush on one chart updates the x-scale for all connected charts.
Pro Tip
If you want to combine brush selection with zoom/pan, you can add .interactive() to the concatenated chart alongside the selection—Altair handles this gracefully in most cases.
内容的提问来源于stack exchange,提问作者bart van deenen

