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

如何用Plotly Express实现多类别同Y轴散点及堆叠子图?

问题描述

我用Plotly绘制散点图,X轴为时间字段DATE,Y轴为分类变量CODE,按SOURCE字段上色。目前遇到两个问题:

  1. 如何让不同SOURCE的点显示在同一个自定义Y轴上(当前并非同一Y轴);
  2. 如何将每个CODE类别放在独立图表中并堆叠展示?

样本数据

IDDATECODESOURCE
P042016-08-08fm1
P042015-05-08fm1
P042010-07-20vm3
P042013-12-06gm4
P082018-03-01hm4

当前代码

def char():
    color_discrete_map = {'df1': 'rgb(255,0,0)',
                         'df2': 'rgb(0,255,0)',
                         'df3': '#11FCE4',
                         'df4': '#9999FF',
                         'df5': '#606060',
                         'df6': '#CC6600'}

    fig = px.scatter(df, x='DATE', y='CODE', color='SOURCE', width=800,
                     height=500, color_discrete_map=color_discrete_map)

    fig.update_layout(xaxis_type='category')

    fig.update_layout(
        margin=dict(l=250, r=0, t=0, b=20),
    )
    fig.update_layout(xaxis=dict(tickformat="%y-%m"))

    fig.update_xaxes(ticks= "outside",
                     ticklabelmode= "period", 
                     tickcolor= "black", 
                     ticklen=10, 
                     minor=dict(
                         ticklen=4,  
                         dtick=7*24*60*60*1000,  
                         tick0="2016-07-03", 
                         griddash='dot', 
                         gridcolor='white')
                    )

    st.plotly_chart(fig)

效果对比

期望效果

期望效果

当前实现效果

当前效果


解决方案

问题1:让不同SOURCE共享同一Y轴

当前不同SOURCE的点不在同一Y轴,是因为CODE分类在不同SOURCE中无交叉,导致Plotly自动分割Y轴范围。可通过强制统一Y轴分类顺序解决:

  1. 提取所有CODE唯一值并自定义排序:
code_categories = sorted(df['CODE'].unique())
  1. 绘图时通过category_orders参数强制Y轴分类顺序,确保所有点映射到同一组刻度:
fig = px.scatter(df, x='DATE', y='CODE', color='SOURCE', width=800,
                 height=500, color_discrete_map=color_discrete_map,
                 category_orders={'CODE': code_categories})
  1. 修正X轴类型:DATE是时间字段,应设置为'date'而非'category',避免日期被当作独立分类:
fig.update_layout(xaxis_type='date')

问题2:每个CODE类别独立图表并堆叠展示

使用Plotly的make_subplots创建垂直堆叠子图,每个子图对应一个CODE类别:

  1. 导入子图工具:
from plotly.subplots import make_subplots
  1. 创建堆叠子图布局,共享X轴:
code_list = sorted(df['CODE'].unique())
fig = make_subplots(rows=len(code_list), cols=1, shared_xaxes=True,
                    vertical_spacing=0.05, subplot_titles=[f'CODE: {code}' for code in code_list])
  1. 遍历每个CODE,将对应数据点添加到子图:
# 匹配SOURCE的颜色,根据实际值调整
color_map = {'m1': 'rgb(255,0,0)', 'm3': '#11FCE4', 'm4': '#9999FF'}

for idx, code in enumerate(code_list, 1):
    subset = df[df['CODE'] == code]
    for source in subset['SOURCE'].unique():
        source_subset = subset[subset['SOURCE'] == source]
        fig.add_scatter(x=source_subset['DATE'], y=[code]*len(source_subset),
                        mode='markers', marker_color=color_map.get(source, '#606060'),
                        name=f'SOURCE: {source}', row=idx, col=1)

# 调整布局样式
fig.update_layout(height=300*len(code_list), width=800, margin=dict(l=250, r=0, t=50, b=20))
fig.update_xaxes(tickformat="%y-%m", ticks="outside", tickcolor="black", ticklen=10,
                 minor=dict(ticklen=4, dtick=7*24*60*60*1000, tick0="2016-07-03", griddash='dot', gridcolor='white'))
fig.update_yaxes(showticklabels=False)  # 子图标题已标注CODE,可隐藏Y轴刻度
  1. 用Streamlit展示:
st.plotly_chart(fig)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 02:15:14