Reputation: 48
I need to visually compare two signals and I'm using Altair to plot some interactive charts like the example below.
import altair as alt
import pandas as pd
import numpy as np
np.random.seed(42)
df_comparison = pd.DataFrame({'x1': np.arange(20), 'x2': np.arange(20)}) #just for example purposes, actual data will be more interesting
df_signal_1 = pd.DataFrame({'x1': np.arange(20), 'data_1': np.random.random(20)})
df_signal_2 = pd.DataFrame({'x2': np.arange(20), 'data_2': np.random.random(20)})
comparison = alt.Chart(df_comparison, title='Comparison').mark_point(filled=True).encode(
alt.X('x1'),
alt.Y('x2')
).interactive()
signal_1 = alt.Chart(df_signal_1,title='Signal 1').mark_line().encode(
alt.X('x1'),
alt.Y('data_1'),
)
signal_2 = alt.Chart(df_signal_2, title='Signal 2').mark_line().encode(
alt.X('x2'),
alt.Y('data_2'),
)
(signal_1 & (comparison | signal_2).resolve_scale(x='shared')).resolve_scale(x='shared')
By zooming the Comparison chart you can see that its "x1" axis is linked to the "x1" axis of Signal 1, which is fine. However, it is also linked to "x2" axis of Signal 2 and that is not good. How can I link the "x2" axes of the Comparison and Signal 2 charts without breaking the link between the "x1" axes?
Upvotes: 1
Views: 580
Reputation: 86533
You can do this by creating the interaction manually, and then linking domains to the selection's encodings; something like this:
x12_zoom = alt.selection_interval(encodings=['x', 'y'], bind='scales')
comparison = alt.Chart(df_comparison, title='Comparison').mark_point(filled=True).encode(
alt.X('x1'),
alt.Y('x2'),
).add_selection(x12_zoom)
signal_1 = alt.Chart(df_signal_1,title='Signal 1').mark_line().encode(
alt.X('x1', scale=alt.Scale(domain={'selection': x12_zoom.name, 'encoding': 'x'})),
alt.Y('data_1'),
)
signal_2 = alt.Chart(df_signal_2, title='Signal 2').mark_line().encode(
alt.X('x2', scale=alt.Scale(domain={'selection': x12_zoom.name, 'encoding': 'y'})),
alt.Y('data_2'),
)
(signal_1 & (comparison | signal_2))
Upvotes: 1