You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Altair中为折线分段按y值设色:y>1红,y<1绿?

在Altair中为折线分段设置不同颜色

问题

想要将折线中y值高于1的分段设为红色,低于1的分段设为绿色,但直接通过mark_line的color条件编码得到的是渐变线段,不符合需求:

现有代码

import pandas as pd
import altair as alt

df = pd.DataFrame({
    'x': [1, 2, 3, 4, 5],
    'y': [0.8, 0.9, 1.1, 1.0, 0.9]
})
alt.Chart(df).mark_line(
    point=True,
    line=True,
).encode(
    alt.X("x", type="quantitative"),
    alt.Y("y", type="quantitative"),
    color=alt.Color(
        condition={
            "test": "datum.y < 1",
            "value": "green"
        },
        value="red",
    ),
).save("plot.html")

当前效果

折线颜色随数据点的y值渐变,相邻点颜色不同时线段呈现过渡色,无法实现纯色分段。

期望效果

折线被拆分为独立的纯色分段:

  • x=1到x=2的线段为绿色(y值均<1)
  • x=2到x=3的线段为红色(跨y=1阈值,包含y>1的部分)
  • x=3到x=4的线段为红色(y值≥1)
  • x=4到x=5的线段为绿色(y值<1)

原因

mark_line的颜色编码是基于数据点的,会自动在相邻点的颜色之间插值,导致线段渐变,无法实现纯色分段的效果。

解决方案

需要先将原始数据转换为线段级数据(每个线段对应两个连续的点),再用mark_rule绘制每个独立线段并设置颜色:

1. 预处理生成线段数据

将连续点两两配对,生成包含线段起止坐标的DataFrame,并根据线段的y值范围判断颜色:

import pandas as pd
import altair as alt

df = pd.DataFrame({
    'x': [1, 2, 3, 4, 5],
    'y': [0.8, 0.9, 1.1, 1.0, 0.9]
})

# 生成线段数据
segments = []
for i in range(len(df) - 1):
    curr = df.iloc[i]
    nxt = df.iloc[i+1]
    # 判断线段是否需要设为红色:只要端点有一个>1,或跨阈值
    use_red = curr['y'] > 1 or nxt['y'] > 1 or (curr['y'] < 1 and nxt['y'] > 1)
    segments.append({
        'x_start': curr['x'],
        'x_end': nxt['x'],
        'y_start': curr['y'],
        'y_end': nxt['y'],
        'segment_color': 'red' if use_red else 'green'
    })
seg_df = pd.DataFrame(segments)

2. 绘制分段折线与点

用mark_rule绘制每个独立线段,再叠加原始数据点:

# 绘制分段线段
line_layer = alt.Chart(seg_df).mark_rule(strokeWidth=2).encode(
    x='x_start:Q',
    x2='x_end:Q',
    y='y_start:Q',
    y2='y_end:Q',
    color=alt.Color('segment_color:N', scale=None)  # 禁用自动颜色刻度,使用自定义颜色
)

# 绘制原始数据点
point_layer = alt.Chart(df).mark_point(
    fill='white', strokeWidth=2, size=100
).encode(
    x='x:Q',
    y='y:Q',
    color=alt.Color(
        condition={'test': 'datum.y < 1', 'value': 'green'},
        value='red'
    )
)

# 组合图层并保存
final_chart = line_layer + point_layer
final_chart.save("plot.html")

说明

  • mark_rule支持通过x/x2和y/y2定义线段,每个线段对应一行数据,能单独控制颜色
  • 颜色判断逻辑可根据需求调整:比如仅当线段两端都>1时设为红色,或只要有一个端点>1就设为红色
  • 叠加的点保持了原始需求中的样式,与分段线段颜色一致

内容的提问来源于stack exchange,提问作者magum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 22:10:12