简体   繁体   中英

Dual Axis on Altair - filtering source

Altair charting is brilliant in Python because it's easy to add hover-over data annotations (unlike Seaborn) and adding additional 'marks' (lines, bars etc) is cleaner than Plotly, but one thing am struggling with is dual axis. This generally works fine (similar to documentation https://altair-viz.github.io/gallery/layered_chart_with_dual_axis.html ):

import altair as alt
from vega_datasets import data
source = data.seattle_weather()

chart_base = alt.Chart(source.query("weather != 'snow'")).encode(
    alt.X('date:T',
    axis=alt.Axis(),
    scale=alt.Scale(zero=False)
    )
).properties(width=800, height=400)

line_prec = chart_base.mark_line(color='blue', size=1).encode(y='mean(precipitation)')
line_temp = chart_base.mark_line(color='red', size=1).encode(y='mean(temp_max)')
alt.layer(line_prec, line_temp).resolve_scale(y='independent')

在此处输入图片说明

... so all I need to do is filter the individual marks, similar to the source.query but say we want to show precipitation only where "weather == 'rain'" and temp_max where "weather != 'rain'" (yes not analytically insightful but just to illustrate working example of double filter).

Solution could have been Altair combining multiple data sets but the DRYer code is not dual axis and more promising but the multiple layer method doesn't seem to apply to dual axis, as we get error trying to add (rather desperately) the .resolve_scale(y='independent'):

chart_precip = alt.Chart(source.query("weather == 'rain'")).mark_line(color='blue', size=1).encode(
    y='mean(precipitation)', 
    x=('date:T')
).properties(width=500, height=300) #.resolve_scale(y='independent') # can't add resolve_scale

chart_temp = alt.Chart(source.query("weather != 'rain'")).mark_line(color='red', size=1).encode(
    y='mean(temp_max)', 
    x=('date:T')
).properties(width=500, height=300) #.resolve_scale(y='independent') # can't add resolve_scale

chart_precip + chart_temp

It works but does not label the dual axis, which is no good:

在此处输入图片说明

So... is there a way to simply have dual axis marks filtered individually?

You can achieve dual axes by setting resolve_scale(y='independent') on the layered chart rather than the individual layers:

(chart_precip + chart_temp).resolve_scale(y='independent')

在此处输入图片说明

Note that chart_precip + chart_temp is just a shorthand for alt.layer(chart_precip, chart_temp) , so this is quite similar to your first example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM