Dravidian
Dravidian

Reputation: 9945

Altair : Make Interval Selection Line plot with dual axis and datetime x axis

I am trying to make a dual y axis line plot with date time index as x axis, with interval selection, so far :

#base encoding the X-axis
brush = alt.selection(type='interval', encodings=['x'])
base = alt.Chart(yData.reset_index())
base = base.encode(alt.X('{0}:T'.format(yData.index.name), 
                         axis=alt.Axis(title=yData.index.name)))

py = base.mark_line()
py = py.encode(alt.X('date:T',scale = alt.Scale(domain = brush)),
               alt.Y('plotY', axis=alt.Axis(title='ylabel1')))
py = py.properties(width = 700, height = 230)


px = base.mark_line()
px = px.encode(alt.Y('plotX1', axis=alt.Axis(title='ylabel2')))
px = px.properties(width = 700, height = 230)

upper = (py + px).resolve_scale(y='independent')

lower = upper.copy()
lower = lower.properties(height=20).add_selection(brush)

p = alt.vconcat(upper, lower).configure_concat(spacing=0)
p

If I try to produce p I am getting the following error :

Javascript Error: Duplicate signal name: "selector045_x"
This usually means there's a typo in your chart specification. See the JavaScript console for the full traceback

If I try to produce upper I get:

enter image description here

My dataframe :

enter image description here

Any idea how can I get interval selection here?

Also I keep getting this error while working with Altair, any idea how can I debug this?? I have no experience in java, and am using a Mac.

EDIT

After adding the selection to only one of the subplots,

brush = alt.selection(type='interval', encodings=['x'])
base = alt.Chart(yData.reset_index())
base = base.encode(alt.X('{0}:T'.format(yData.index.name), 
                         axis=alt.Axis(title=yData.index.name)))

py = base.mark_line()
py = py.encode(alt.X('date:T',scale = alt.Scale(domain = brush)),
               alt.Y('plotY', axis=alt.Axis(title='ylabel1')))
py = py.properties(width = 700, height = 230).add_selection(brush)


px = base.mark_line()
px = px.encode(alt.Y('plotX1', axis=alt.Axis(title='ylabel2')))
px = px.properties(width = 700, height = 230)

upper = (py + px).resolve_scale(y='independent')

lower = upper.copy()
lower = lower.properties(height=20)

p = alt.vconcat(upper, lower).configure_concat(spacing=0)
p

I am getting this :

enter image description here

(1) The selection isn't working

(2) And somehow i am getting an exact replica of upper for the lower plot

**EDIT -- This made it work **

brush = alt.selection(type='interval', encodings=['x'])
base = alt.Chart(yData.reset_index())
base = base.encode(alt.X('{0}:T'.format(yData.index.name), 
                         axis=alt.Axis(title=yData.index.name)))

py = base.mark_line(color='orange')
py = py.encode(alt.X('date:T',scale = alt.Scale(domain = brush)),
               alt.Y('plotY', axis=alt.Axis(title='ylabel1')),
              )
py = py.properties(width = 700, height = 230)


px = base.mark_line()
px = px.encode(alt.X('date:T',scale = alt.Scale(domain = brush)),
               alt.Y('plotX1', axis=alt.Axis(title='ylabel2')))
px = px.properties(width = 700, height = 230)

# upper = px
upper = (py + px).resolve_scale(y='independent')
lower = px.copy()
lower = lower.properties(height=20).add_selection(brush)

p = alt.vconcat(upper, lower).configure_concat(spacing=0)
p

enter image description here

Upvotes: 0

Views: 1182

Answers (1)

jakevdp
jakevdp

Reputation: 86330

Add the selection to just px or py instead. If you add the same selection to both subcharts in a layer, it results in this error. This is a bug that should probably be fixed in Altair.

To be more concrete, your code should look like this:

# ...
px = px.properties(width = 700, height = 230).add_selection(brush)  # add selection here
# ...
lower = lower.properties(height=20)  # not here
# ...

Upvotes: 2

Related Questions