Reputation: 4544
I'm trying to plot data and compare it to a threshold set at a fixed value. When creating a layer
ed chart, the y axis does not appear to hold for both layers. The same goes for hconcat
.
I found this issue which mentions .resolve_scale(y='shared')
, but that doesn't seem to work. When I specify the rule to be at 5, it appears above 15.
np.random.seed(42)
df = pd.DataFrame({
'x': np.linspace(0, 10, 500),
'y': np.random.randn(500).cumsum()
})
base = alt.Chart(df)
line = base.mark_line().encode(x='x', y='y')
rule = base.mark_rule().encode(y=alt.value(5))
alt.layer(line, rule).resolve_scale(y='shared')
To get the rule to appear at the value 5, I have to set it at 110.
rule = base.mark_rule().encode(y=alt.value(110))
alt.layer(line, rule).resolve_scale(y='shared')
How can I edit the chart so that the rule shows at the y-value specified?
Upvotes: 1
Views: 1904
Reputation: 86330
Altair scales map a domain to a range. The domain describes the extent of the data values, while the range describes the extent of the visual features to which those values are mapped. For color encodings, the range might be "red"
, "blue"
, "green"
, etc. For positional encodings like x
and y
, the range is the pixel position of the mark on the chart.
When you use alt.value
, you are specifying the range value, not the domain value. This is why you can use an encoding like color=alt.value('red')
, to specify that you want the mark to appear as the color red. When you do y=alt.value(5)
, you are saying you want the mark to appear 5 pixels from the top of the y-axis.
Recent versions of Vega-Lite added the ability to specify the domain value via datum
rather than value
, but unfortunately Altair does not yet support this, and so the only way to make this work is to have a data field with the desired value. For example:
line = base.mark_line().encode(x='x', y='y')
rule = alt.Chart(pd.DataFrame({'y': [5]})).mark_rule().encode(y='y')
alt.layer(line, rule).resolve_scale(y='shared')
Upvotes: 2