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

Plotly中按分类字段为单条折线设置红绿分段颜色的方法

问题描述

现有包含正弦形态数值的数据集,包含tag、num1、num1_color、num2、num2_color共5列,需要基于Plotly绘制折线图:

  • x轴映射tag列
  • y轴分别映射num1、num2列
  • 折线颜色规则:num1折线颜色随num1_color列值动态变化,num2折线颜色随num2_color列值动态变化,其中G对应绿色、R对应红色(颜色判定规则为当前值较前值上涨标G、下跌标R)
  • 预期效果:
    预期效果图

可复现基础代码

样例数据构造

import pandas as pd
import numpy as np

# 构造样例DataFrame
ty =  pd.DataFrame()
ty['tag'] = [1,2,3,4,5,6,7,8,9,10,11]
ty['num1'] = [0.0, 0.9096319953545183, 0.7557495743542583, -0.2817325568414294,
 -0.9898214418809327, -0.5406408174555974, 0.5406408174555971, 0.9898214418809328,
 0.2817325568414299, -0.7557495743542577, -0.9096319953545183]
ty['num1_color'] = np.where(ty['num1'] >ty['num1'].shift(1) , 'G' , 'R')
ty['num2'] = [0.0, 0.9898214418809328, -0.2817325568414294, -0.9096319953545186,
 0.5406408174555971, 0.7557495743542594, -0.7557495743542577, -0.5406408174555977,
 0.9096319953545179, 0.28173255684143184, -0.9898214418809322]
ty['num2_color'] = np.where(ty['num2'] >ty['num2'].shift(1) , 'G' , 'R')

运行后数据预览如下:

tagnum1num1_colornum2num2_color
10.000000R0.000000R
20.909632G0.989821G
30.755750R-0.281733R
4-0.281733R-0.909632R
5-0.989821R0.540641G
6-0.540641G0.755750G
70.540641G-0.755750R
80.989821G-0.540641G
90.281733R0.909632G
10-0.755750R0.281733R
11-0.909632R-0.989821R

初始绘图代码

初始代码仅支持为整条折线设置单一固定颜色,无法实现分段变色效果:

import plotly
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots


fig = go.Figure()
fig = make_subplots(specs=[{"secondary_y": True}])
x = ty['tag'];y1=ty['num1'];y2=ty['num2']
fig.add_trace(go.Scatter(x=x, y=y1,
                         mode='lines',
                         marker_color='blue',
                         name='macd'), secondary_y=False)
fig.add_trace(go.Scatter(x=x, y=y2,
                         mode='lines',
                         marker_color='red',
                         name='signal'), secondary_y=False)
fig.show()

改造实现方案

Plotly单条Scatter轨迹不支持单条折线分段设置颜色,实现逻辑为:按颜色标签将折线拆分为多个连续同色线段,每个线段单独作为一条轨迹添加,同系列同色线段统一绑定图例组,保证点击图例可同时隐藏/显示同系列所有线段,和单条轨迹的交互体验一致。

改造后完整可运行代码:

import pandas as pd
import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# 复用样例数据构造逻辑
ty =  pd.DataFrame()
ty['tag'] = [1,2,3,4,5,6,7,8,9,10,11]
ty['num1'] = [0.0, 0.9096319953545183, 0.7557495743542583, -0.2817325568414294,
 -0.9898214418809327, -0.5406408174555974, 0.5406408174555971, 0.9898214418809328,
 0.2817325568414299, -0.7557495743542577, -0.9096319953545183]
ty['num1_color'] = np.where(ty['num1'] >ty['num1'].shift(1) , 'G' , 'R')
ty['num2'] = [0.0, 0.9898214418809328, -0.2817325568414294, -0.9096319953545186,
 0.5406408174555971, 0.7557495743542594, -0.7557495743542577, -0.5406408174555977,
 0.9096319953545179, 0.28173255684143184, -0.9898214418809322]
ty['num2_color'] = np.where(ty['num2'] >ty['num2'].shift(1) , 'G' , 'R')

# 颜色映射规则
color_map = {'G': 'green', 'R': 'red'}

def add_segment_line(fig, df, x_col, y_col, color_col, series_name, color_map, secondary_y=False):
    """
    按颜色标签分段绘制折线,同系列线段共享图例交互
    :param fig: Plotly画布对象
    :param df: 输入数据集
    :param x_col: x轴对应列名
    :param y_col: y轴对应列名
    :param color_col: 颜色标签对应列名
    :param series_name: 系列名称(用于图例展示)
    :param color_map: 颜色标签到实际色值的映射字典
    :param secondary_y: 是否绘制在次坐标轴
    """
    first_trace = True
    # 遍历所有相邻点对,两点间线段颜色由后一个点的颜色标签决定
    for i in range(1, len(df)):
        segment_x = [df.loc[i-1, x_col], df.loc[i, x_col]]
        segment_y = [df.loc[i-1, y_col], df.loc[i, y_col]]
        line_color = color_map[df.loc[i, color_col]]
        fig.add_trace(
            go.Scatter(
                x=segment_x,
                y=segment_y,
                mode='lines',
                line=dict(color=line_color, width=2),
                name=series_name,
                legendgroup=series_name,
                showlegend=True if first_trace else False
            ),
            secondary_y=secondary_y
        )
        first_trace = False

# 创建画布并绘图
fig = make_subplots(specs=[{"secondary_y": True}])
add_segment_line(fig, ty, x_col='tag', y_col='num1', color_col='num1_color',
                 series_name='num1', color_map=color_map, secondary_y=False)
add_segment_line(fig, ty, x_col='tag', y_col='num2', color_col='num2_color',
                 series_name='num2', color_map=color_map, secondary_y=False)

# 布局调整
fig.update_layout(
    title='正弦形态数据分段着色折线图',
    xaxis_title='tag',
    yaxis_title='数值',
    legend_title='数据系列'
)
fig.show()

代码说明

  • 线段绘制以相邻两个点为最小单元,线段颜色取终点对应的颜色标签,完全匹配“当前值相对前值涨跌决定颜色”的规则
  • 通过legendgroup参数绑定同系列所有线段,图例交互逻辑和单条折线完全一致
  • 线段宽度、颜色色值、坐标轴配置可根据实际需求调整参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 14:42:16