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

Plotly中如何在K线及均线后方绘制区间填充区域

解决方案:在Plotly中底层绘制区间填充

问题分析

你遇到的核心问题有两个:

  1. 用trace填充时会覆盖上层的K线和均线(Plotly暂不支持zorder设置,只能靠元素添加顺序或shape的layer参数控制层级)
  2. 之前的path shape代码因坐标格式错误无法生成图形,而逐个绘制矩形效率太低

正确实现方法:修复Path Shape代码

Plotly的path命令要求坐标为x,y的格式,而非元组形式。只需修正坐标拼接逻辑,再通过layer='below'参数将shape置于所有trace下方,即可高效生成底层填充区间。

完整代码示例

import plotly.graph_objects as go
import pandas as pd

# 示例数据(替换为你的DataFrame)
data = {
    'Date': ['1/3/2021']*10,
    'Time': ['22:01:00','22:02:00','22:03:00','22:04:00','22:05:00','22:06:00','22:07:00','22:08:00','22:09:00','22:10:00'],
    'Open': [1.77089,1.77141,1.77112,1.77121,1.7711,1.77117,1.77086,1.77088,1.77084,1.7707],
    'High': [1.77126,1.77141,1.77146,1.77277,1.77132,1.77117,1.77086,1.77088,1.77084,1.77084],
    'Low': [1.77089,1.77126,1.77112,1.77114,1.77094,1.77052,1.7706,1.77086,1.77071,1.77064],
    'Close': [1.77126,1.77126,1.77136,1.77127,1.77094,1.77052,1.77083,1.77086,1.77071,1.77064],
    'ZoneBot': [1.772686,1.772704,1.772726,1.772747,1.772768,1.772784,1.772796,1.772811,1.772826,1.772839],
    'ZoneTop': [1.773486,1.773504,1.773526,1.773547,1.773568,1.773584,1.773596,1.773611,1.773626,1.773639]
}
df = pd.DataFrame(data)
# 合并DateTime作为索引(确保x轴为时间类型)
df['DateTime'] = pd.to_datetime(df['Date'] + ' ' + df['Time'])
df.set_index('DateTime', inplace=True)

fig = go.Figure()

# --------------------------
# 1. 首先添加底层区间填充Shape
# --------------------------
# 修正Path命令的坐标格式:x,y 而非 (x,y)
path_commands = f"M{df.index[0].timestamp()},{df['ZoneBot'].iloc[0]} "
# 绘制ZoneBot的折线
for i in range(1, len(df)):
    path_commands += f"L{df.index[i].timestamp()},{df['ZoneBot'].iloc[i]} "
# 反向绘制ZoneTop的折线,形成闭合区域
for i in range(len(df)-1, -1, -1):
    path_commands += f"L{df.index[i].timestamp()},{df['ZoneTop'].iloc[i]} "
# 闭合路径
path_commands += "Z"

fig.add_shape(
    type='path',
    path=path_commands,
    fillcolor='rgba(0,0,0,0.5)',  # 使用半透明黑色避免完全遮挡底层网格
    line=dict(color='black'),
    opacity=0.5,
    xref='x',
    yref='y',
    layer='below'  # 关键:将shape置于所有trace下方
)

# --------------------------
# 2. 添加K线图Trace
# --------------------------
fig.add_trace(go.Candlestick(
    x=df.index,
    open=df['Open'],
    high=df['High'],
    low=df['Low'],
    close=df['Close'],
    name='OHLC'
))

# --------------------------
# 3. 添加移动平均线Trace(示例:简单均线,替换为你的MA数据)
# --------------------------
df['MA'] = df['Close'].rolling(window=3).mean()
fig.add_trace(go.Scatter(
    x=df.index,
    y=df['MA'],
    mode='lines',
    name='MA',
    line=dict(color='blue', width=2)
))

# 调整布局
fig.update_layout(
    title='OHLC with MA and Zone',
    xaxis_title='Time',
    yaxis_title='Price',
    xaxis_rangeslider_visible=False
)

fig.show()

关键修正点

  1. Path坐标格式:将M{df.index[0],df[f"ZoneBot"][0]}改为M{df.index[0].timestamp()},{df['ZoneBot'].iloc[0]},确保坐标为x,y的字符串格式(如果x轴是时间类型,需转换为timestamp或直接使用Plotly支持的时间字符串格式)
  2. Layer参数:通过layer='below'强制将shape置于所有trace底层,无需担心添加顺序(先加shape再加trace更稳妥)
  3. 效率优化:仅需一个shape即可完成整个区间填充,避免了大量矩形shape导致的性能问题

备选方案:使用填充Trace并调整添加顺序

如果你更倾向于用trace填充,只需先添加填充trace,再添加K线和均线,因为Plotly的trace是按添加顺序叠放(后添加的在上方):

# 先添加填充区间
fig.add_trace(go.Scatter(
    x=df.index.tolist() + df.index.tolist()[::-1],
    y=df['ZoneBot'].tolist() + df['ZoneTop'].tolist()[::-1],
    fill='toself',
    fillcolor='rgba(0,0,0,0.5)',
    line=dict(color='rgba(0,0,0,0)'),  # 隐藏边界线
    name='Zone',
    hoverinfo='skip'
))
# 再添加K线和均线...

这种方法无需处理path命令,但要注意必须先添加填充trace,否则会覆盖上层元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 16:33:09