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

使用pandas groupby实现带置信区间的Plotly分组折线图对比多场景

实现方案

你需要手动遍历所有分组组合为每个组添加置信区间填充层,两种可视化库均可实现,具体实现代码如下:

Plotly 实现方案

核心思路是用make_subplots创建分面网格,遍历second_factor(分面维度)和first_factor(颜色分组维度)的所有组合,为每个组合依次添加置信区间填充和均值线:

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

# 提取唯一分组值
first_factors = reset_df['first_factor'].unique()
second_factors = reset_df['second_factor'].unique()
# 自定义分组颜色,长度与first_factor数量一致即可
color_palette = ['rgb(31, 119, 255)', 'rgb(255, 127, 14)', 'rgb(44, 160, 44)', 'rgb(214, 39, 40)']

# 创建1行N列的分面图,共享Y轴
fig = make_subplots(
    rows=1, cols=len(second_factors),
    subplot_titles=[f'second_factor={s}' for s in second_factors],
    shared_yaxes=True
)

for col_idx, sec_factor in enumerate(second_factors, 1):
    for color_idx, first_factor in enumerate(first_factors):
        # 筛选当前分组的时序数据
        filter_df = reset_df[
            (reset_df['first_factor'] == first_factor) & 
            (reset_df['second_factor'] == sec_factor)
        ].sort_values('tick')
        curr_color = color_palette[color_idx]
        fill_color = curr_color.replace('rgb', 'rgba').replace(')', ',0.3)')

        # 添加上置信区间边界(透明线,仅做填充锚点)
        fig.add_trace(go.Scatter(
            x=filter_df['tick'], y=filter_df['ci95_hi'],
            line=dict(width=0, color=curr_color),
            mode='lines', showlegend=False, hoverinfo='skip'
        ), row=1, col=col_idx)

        # 添加下置信区间边界 + 填充到上边界
        fig.add_trace(go.Scatter(
            x=filter_df['tick'], y=filter_df['ci95_lo'],
            line=dict(width=0, color=curr_color),
            mode='lines', fill='tonexty', fillcolor=fill_color,
            name=f'95%CI {first_factor}', showlegend=col_idx==1 # 仅第一个分面显示图例避免重复
        ), row=1, col=col_idx)

        # 添加均值线
        fig.add_trace(go.Scatter(
            x=filter_df['tick'], y=filter_df['mean'],
            line=dict(width=2, color=curr_color),
            mode='lines', name=f'均值 {first_factor}', showlegend=col_idx==1
        ), row=1, col=col_idx)

# 全局布局配置
fig.update_layout(
    title='多场景时序均值与95%置信区间',
    xaxis_title='Tick', yaxis_title='数值',
    hovermode='x'
)
fig.show()

如果不需要分面,仅在单图中区分所有分组,删除分面逻辑、给不同second_factor组合配置不同线型即可。


Bokeh 实现方案

Bokeh可以用varea接口直接绘制填充区间,配合网格布局实现分面效果:

from bokeh.plotting import figure, show
from bokeh.layouts import gridplot
from bokeh.palettes import Category10

first_factors = reset_df['first_factor'].unique()
second_factors = reset_df['second_factor'].unique()
color_palette = Category10[len(first_factors)] if len(first_factors) <=10 else Category20[len(first_factors)]

plot_list = []
for sec_factor in second_factors:
    p = figure(title=f'second_factor={sec_factor}', x_axis_label='Tick', y_axis_label='数值')
    for color_idx, first_factor in enumerate(first_factors):
        filter_df = reset_df[
            (reset_df['first_factor'] == first_factor) & 
            (reset_df['second_factor'] == sec_factor)
        ].sort_values('tick')
        curr_color = color_palette[color_idx]
        # 绘制置信区间填充
        p.varea(
            x=filter_df['tick'], y1=filter_df['ci95_lo'], y2=filter_df['ci95_hi'],
            alpha=0.3, color=curr_color, legend_label=f'95%CI {first_factor}'
        )
        # 绘制均值线
        p.line(
            x=filter_df['tick'], y=filter_df['mean'],
            line_width=2, color=curr_color, legend_label=f'均值 {first_factor}'
        )
    plot_list.append(p)

# 横向排列所有分面
show(gridplot([plot_list], width=450, height=400))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 05:48:01