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

如何在Plotly中基于Litho Code条件绘制测井图填充区间

问题:在Plotly测井图中实现基于岩性代码的区间填充效果

我正尝试使用Plotly绘制测井图,但发现Plotly没有Matplotlib中的fill-in-between功能。我希望基于数据框的Litho Code列(值8对应黄色),在特定深度区间添加填充效果,目标效果如图所示。

样本数据

井(Well)深度(Depth)自然伽马(GR)岩性代码(Litho Code)
A146.608863.1578
A146.761259.04578
A146.913657.94258
A147.218460.1089
A147.370859.18628
A147.523257.96268

现有代码

logplot = make_subplots(rows=1, cols=8, shared_yaxes = True)
logplot.add_trace(go.Scatter(x=df['GR'], y=df['DEPTH'], name='GR', line_color='green'), row=1, col=1)
logplot.update_xaxes(col=1, title_text='GR', linecolor='#585858')

logplot.update_xaxes(showline=True, linewidth=2, linecolor='black', mirror=True, ticks='inside', tickangle=0)
logplot.update_yaxes(tickmode='linear', tick0=0, dtick=250, showline=True, linewidth=2, ticks='outside', mirror=True, linecolor='black')
logplot.update_yaxes(row=1, col=1, autorange='reversed')
logplot.update_layout(height=750, width=650, showlegend=False, template = 'plotly', margin={'r':0,'t':50,'l':0,'b':0})

解决方案

Plotly中可以通过add_shape添加矩形的方式实现区间填充,具体步骤如下:

1. 预处理数据,提取连续岩性区间

先识别出所有岩性代码(Litho Code)为8的连续深度段:

# 转换空值为NaN,方便后续处理
df['岩性代码(Litho Code)'] = pd.to_numeric(df['岩性代码(Litho Code)'], errors='coerce')

# 标记连续的岩性区间
df['litho_group'] = (df['岩性代码(Litho Code)'] != df['岩性代码(Litho Code)'].shift()).cumsum()

# 筛选出岩性代码为8的区间,计算每个区间的深度上下限
litho_intervals = df[df['岩性代码(Litho Code)'] == 8].groupby('litho_group').agg(
    min_depth=('深度(Depth)', 'min'),
    max_depth=('深度(Depth)', 'max')
).reset_index(drop=True)

2. 在Plotly图中添加黄色填充矩形

遍历每个岩性区间,用add_shape绘制覆盖GR轴范围的黄色半透明矩形:

# 获取GR轴的数值范围,也可以手动设置固定值(比如0-150)
gr_min = df['自然伽马(GR)'].min()
gr_max = df['自然伽马(GR)'].max()

# 为每个区间添加填充
for idx, row in litho_intervals.iterrows():
    logplot.add_shape(
        type="rect",
        x0=gr_min, x1=gr_max,
        y0=row['min_depth'], y1=row['max_depth'],
        fillcolor="yellow",
        opacity=0.3,  # 调整透明度避免遮挡曲线
        line_width=0,  # 隐藏矩形边框
        row=1, col=1  # 指定填充在GR所在的子图
    )

3. 完整整合代码

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

# 构造样本数据
data = {
    '井(Well)': ['A']*6,
    '深度(Depth)': [146.6088, 146.7612, 146.9136, 147.2184, 147.3708, 147.5232],
    '自然伽马(GR)': [63.1578, 59.0457, 57.9425, 60.1089, 59.1862, 57.9626],
    '岩性代码(Litho Code)': ['', 8, 8, '', 8, 8]
}
df = pd.DataFrame(data)

# 预处理数据,提取连续岩性区间
df['岩性代码(Litho Code)'] = pd.to_numeric(df['岩性代码(Litho Code)'], errors='coerce')
df['litho_group'] = (df['岩性代码(Litho Code)'] != df['岩性代码(Litho Code)'].shift()).cumsum()
litho_intervals = df[df['岩性代码(Litho Code)'] == 8].groupby('litho_group').agg(
    min_depth=('深度(Depth)', 'min'),
    max_depth=('深度(Depth)', 'max')
).reset_index(drop=True)

# 创建测井图
logplot = make_subplots(rows=1, cols=8, shared_yaxes=True)
logplot.add_trace(go.Scatter(x=df['自然伽马(GR)'], y=df['深度(Depth)'], name='GR', line_color='green'), row=1, col=1)
logplot.update_xaxes(col=1, title_text='GR', linecolor='#585858')

# 添加岩性填充
gr_min = df['自然伽马(GR)'].min()
gr_max = df['自然伽马(GR)'].max()
for idx, row in litho_intervals.iterrows():
    logplot.add_shape(
        type="rect",
        x0=gr_min, x1=gr_max,
        y0=row['min_depth'], y1=row['max_depth'],
        fillcolor="yellow",
        opacity=0.3,
        line_width=0,
        row=1, col=1
    )

# 布局设置
logplot.update_xaxes(showline=True, linewidth=2, linecolor='black', mirror=True, ticks='inside', tickangle=0)
logplot.update_yaxes(tickmode='linear', tick0=0, dtick=250, showline=True, linewidth=2, ticks='outside', mirror=True, linecolor='black')
logplot.update_yaxes(row=1, col=1, autorange='reversed')
logplot.update_layout(height=750, width=650, showlegend=False, template='plotly', margin={'r':0,'t':50,'l':0,'b':0})

# 显示图形
logplot.show()

说明:

  • 若需要固定GR轴范围,直接将gr_min和gr_max设为目标数值即可(如gr_min=0, gr_max=150)
  • 调整opacity参数可以控制填充的透明度,平衡填充效果与曲线可读性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 19:48:26