颜色由符号决定的 Altair 面积图

Altair area plot with color determined by sign

我想绘制一个图,在其中对两条曲线之间的区域进行阴影处理,颜色取决于哪条曲线较高(因此,例如,如果“曲线 1”在上方,则曲线之间的区域为绿色“曲线 2”,如果“曲线 1”低于“曲线 2”,则为红色)。下面的情节是我在制作这样的情节时所做的最大努力。结果接近我想要的,但问题是当我不想要它时它连接具有相同符号的区域。 (最显眼的例子是连接“x~0.6”和“x~1.1”的绿色区域。)有没有更好的方法来制作这样的情节?

import altair as alt
import numpy as np
import pandas as pd

df = pd.DataFrame({
    'x': np.linspace(0, 2, 100),
})
df['y1'] = np.sin(2 * np.pi * df.x)
df['y2'] = np.cos(2 * np.pi * df.x)
df['c'] = (df.y1 > df.y2).apply(lambda b: 'darkseagreen' if b else 'indianred')

base_chart = alt.Chart(df, width=1.618 * 400, height=400)
l1 = base_chart.mark_line(stroke='green', strokeWidth=4).encode(
    x='x:Q',
    y=alt.Y('y1:Q', axis=alt.Axis(title='y')),
)
l2 = base_chart.mark_line(stroke='red', strokeWidth=4).encode(
    x='x:Q',
    y='y2:Q',
)
a = base_chart.mark_area().encode(
    x='x:Q',
    y='y1:Q',
    y2='y2:Q',
    fill=alt.Color('c:N', scale=None),
)
alt.layer(a, l1, l2)

我发现我可以使用 impute 来防止绘制区域之间不需要的线条。

import altair as alt
import numpy as np
import pandas as pd

df = pd.DataFrame({
    'x': np.linspace(0, 2, 100),
})
df['y1'] = np.sin(2 * np.pi * df.x)
df['y2'] = np.cos(2 * np.pi * df.x)
df['c'] = (df.y1 > df.y2).apply(lambda b: 'darkseagreen' if b else 'indianred')

base_chart = alt.Chart(df, width=1.618 * 400, height=400)
l1 = base_chart.mark_line(stroke='green', strokeWidth=4).encode(
    x='x:Q',
    y=alt.Y('y1:Q', axis=alt.Axis(title='y')),
)
l2 = base_chart.mark_line(stroke='red', strokeWidth=4).encode(
    x='x:Q',
    y='y2:Q',
)
a = base_chart.mark_area().encode(
    x='x:Q',
    y=alt.Y('y1:Q', impute={'value': None}),
    y2='y2:Q',
    fill=alt.Color('c:N', scale=None),
)
alt.layer(a, l1, l2)