如何实现Plotly/Dash多图表trace颜色一致且区分度高
解决方案
实现思路
- 全局固定类别颜色映射:提前收集所有可能出现的细菌类别,为每个类别分配唯一固定的颜色,所有图表共用同一套映射规则,确保同类别颜色完全一致,不同类别颜色不重复
- 高区分度色板适配多trace场景:选用Plotly内置的
Alphabet离散色板,共包含26种区分度优秀的颜色,完全满足最多20个trace的颜色区分需求,不会出现颜色相近难以辨别的问题
修改后完整代码
import pandas as pd import numpy as np import plotly.express as px from dash.dependencies import Output, Input from dash import dcc from dash import html import dash df_a = pd.DataFrame({"time":pd.Series(pd.date_range("1-nov-2021","2-nov-2021", freq="S")).sample(30), "bacteria_count":np.random.randint(0,500, 30), "bacteria_type":np.random.choice(list("AB"),30)}) df_a["epoch_time_ms"] = df_a["time"].astype(int) / 1000 df_a = df_a.sort_values("time") df_b = pd.DataFrame({"time":pd.Series(pd.date_range("1-nov-2021","2-nov-2021", freq="S")).sample(30), "bacteria_count":np.random.randint(0,500, 30), "bacteria_type":np.random.choice(list("BC"),30)}) df_b["epoch_time_ms"] = df_b["time"].astype(int) / 1000 df_b = df_b.sort_values("time") # --------------------------新增代码开始-------------------------- # 收集所有唯一的细菌类别 all_bacteria_types = pd.unique(pd.concat([df_a["bacteria_type"], df_b["bacteria_type"]])) # 选用26色高区分度离散色板,支持最多26个不同类别的颜色区分,满足20个trace的需求 color_palette = px.colors.qualitative.Alphabet # 生成全局固定的类别-颜色映射字典 global_color_map = {btype: color_palette[i] for i, btype in enumerate(all_bacteria_types)} # --------------------------新增代码结束-------------------------- fig_a = px.line(df_a, x="time", y="bacteria_count", line_shape="hv", markers=True, color='bacteria_type', # 传入全局颜色映射 color_discrete_map=global_color_map) fig_a.update_traces(mode="markers+lines", hovertemplate=None) fig_a.update_layout(hovermode='x unified') fig_b = px.line(df_b, x="epoch_time_ms", y="bacteria_count", line_shape="hv", markers=True, color='bacteria_type', # 传入全局颜色映射 color_discrete_map=global_color_map) fig_b.update_traces(mode="markers+lines", hovertemplate=None) fig_b.update_layout(hovermode='x unified') app = dash.Dash(__name__) # call flask server app.layout = html.Div(children=[ html.Div([ html.Div([ html.H1(children='G_A'), dcc.Graph(id='fig_a-graph', figure=fig_a) ], className='six columns'), html.Div([ html.H1(children='G_B'), dcc.Graph(id='fig_b-graph', figure=fig_b) ], className='six columns') ])]) if __name__ == '__main__': app.run_server(debug=True, port=8086)
关键说明
- 如果后续需要支持更多类别,可将
px.colors.qualitative.Alphabet替换为px.colors.qualitative.Dark24或px.colors.qualitative.Light24,最多可支持24个不同类别的颜色区分。 - 若有新增数据源,只需将新数据的
bacteria_type加入到all_bacteria_types的计算逻辑中,即可自动为新类别分配唯一不重复的颜色。
内容的提问来源于stack exchange,提问作者HCSF
相关产品推荐
相关产品推荐

