Plotly时间线图表如何为y轴不同类别配置两套独立颜色映射
解法说明
问题1:为y轴不同标签分配独立颜色集合
核心思路是先区分不同y类别(即type字段的不同取值)下的标签,为不同类别标签组分配完全不重叠的配色,避免同名标签颜色冲突:
- 新增
type_label组合字段,区分不同type下的同名标签 - 给
type='1'的标签分配暖色系,type='2'的标签分配冷色系,从根源避免颜色重叠 - 将自定义的全局颜色映射表传给绘图参数即可
问题2:同一张图应用两套颜色映射规则
可以通过两种方式实现,按需选择即可:
- 方案1:将两套映射规则提前整合到同一个颜色字典里,一次性传给plotly,代码更简洁,适合仅需区分同类标签配色的场景
- 方案2:分批次添加轨迹,分别筛选不同y类别的数据,用各自的配色规则生成轨迹后添加到同一张图里,适合两套规则差异大的场景
可运行示例代码
import pandas as pd import datetime import plotly.express as px import plotly.graph_objects as go # 原有数据 df = pd.DataFrame(dict({ 'beginTime': [ datetime.datetime.strptime('1/1/2008 1:00:15', '%m/%d/%Y %H:%M:%S'), datetime.datetime.strptime('1/1/2008 1:15:15', '%m/%d/%Y %H:%M:%S'), datetime.datetime.strptime('1/1/2008 2:00:15', '%m/%d/%Y %H:%M:%S'), datetime.datetime.strptime('1/1/2008 1:00:15', '%m/%d/%Y %H:%M:%S'), datetime.datetime.strptime('1/1/2008 1:02:15', '%m/%d/%Y %H:%M:%S'), datetime.datetime.strptime('1/1/2008 1:20:15', '%m/%d/%Y %H:%M:%S'), ], 'endTime': [ datetime.datetime.strptime('1/1/2008 1:10:15', '%m/%d/%Y %H:%M:%S'), datetime.datetime.strptime('1/1/2008 1:35:15', '%m/%d/%Y %H:%M:%S'), datetime.datetime.strptime('1/1/2008 2:07:15', '%m/%d/%Y %H:%M:%S'), datetime.datetime.strptime('1/1/2008 1:08:15', '%m/%d/%Y %H:%M:%S'), datetime.datetime.strptime('1/1/2008 1:12:15', '%m/%d/%Y %H:%M:%S'), datetime.datetime.strptime('1/1/2008 1:59:15', '%m/%d/%Y %H:%M:%S'), ], 'type': ['1', '1', '1', '2', '2', '2'], 'activity': ['competition1', 'competition1', 'competition1', 'competition2', 'competition2', 'competition2'], 'label': ['eat', 'sleep', 'write', 'write', 'code', 'sleep'] } )) # ---------------------- 方案1:自定义全局颜色映射 ---------------------- # 新增组合字段区分不同type下的同名label df['type_label'] = df['type'] + '_' + df['label'] # 自定义两套不重叠的配色 color_map = { '1_eat': '#e63946', '1_sleep': '#f4a261', '1_write': '#e9c46a', '2_write': '#2a9d8f', '2_code': '#219ebc', '2_sleep': '#8ecae6' } fig = px.timeline(df, x_start="beginTime", x_end="endTime", y="type", color='type_label', color_discrete_map=color_map) # 可选:修改图例显示,只展示label名 for trace in fig.data: trace.name = trace.name.split('_')[1] fig.show() # ---------------------- 方案2:分批次添加独立轨迹 ---------------------- fig = go.Figure() # 先画type=1的数据,用第一套配色 df_type1 = df[df['type'] == '1'] color_map1 = {'eat': 'red', 'sleep': 'orange', 'write': 'gold'} for label in df_type1['label'].unique(): tmp = df_type1[df_type1['label'] == label] fig.add_trace(go.Bar( x=tmp['endTime'] - tmp['beginTime'], y=tmp['type'], base=tmp['beginTime'], orientation='h', name=f'{label}(type1)', marker_color=color_map1[label] )) # 再画type=2的数据,用第二套完全独立的配色 df_type2 = df[df['type'] == '2'] color_map2 = {'write': 'darkblue', 'code': 'darkgreen', 'sleep': 'lightblue'} for label in df_type2['label'].unique(): tmp = df_type2[df_type2['label'] == label] fig.add_trace(go.Bar( x=tmp['endTime'] - tmp['beginTime'], y=tmp['type'], base=tmp['beginTime'], orientation='h', name=f'{label}(type2)', marker_color=color_map2[label] )) fig.update_layout(barmode='overlay') fig.show()
内容的提问来源于stack exchange,提问作者nim_10
相关产品推荐
相关产品推荐

