如何在Plotly中为不同版本前缀的标记点设置差异化颜色
实现Plotly标记点按版本前缀和子版本自定义颜色
需求说明
需要为Plotly散点图中的标记点按以下规则设置颜色:
- 所有以17开头的版本使用一种颜色,18开头的用另一种,20开头的再用一种
- 子版本(如17.2.3、17.2.2等)也需要设置不同颜色
现有数据集
Days Difference commitDate Year-Month 18538 1291 2021-01-25 11:15:48 2020-01 18539 1135 2020-11-30 05:11:41 2020-11 18540 1100 2020-08-17 07:22:54 2020-08 18541 900 2020-08-17 07:12:05 2020-01 18542 340 2020-01-09 06:21:03 2020-01 18543 203 2019-11-20 06:03:28 2019-11 18544 120 2019-11-15 02:50:28 2019-11
现有代码
data1= final_api.query("info_title=='Avi CertificateManagementProfile Object API'") data1['commitDate'] = pd.to_datetime(final_api['commitDate']) import plotly.graph_objects as go fig = go.Figure() fig.add_trace(go.Scatter(mode='lines', x=data1["commitDate"], y=data1["Days_difference"], line_color='black', line_width=1, line_shape='vh', showlegend=False ) ) fig.add_trace(go.Scatter(mode='markers', x=data1["commitDate"], y=data1["Days_difference"], marker=dict(color=data1['day'], colorscale='plasma', size=10), showlegend=False ) ) for _,row in data1.iterrows(): fig.add_annotation( go.layout.Annotation( x=row["commitDate"], y=row["Days_difference"], text=row['info_version'], showarrow=False, align='center', yanchor='bottom', yshift=10, textangle=-90) ) fig.update_layout(template='plotly_white',title_text=' Version Change in Avi CertificateManagementProfile Object API over its Age',title_x=0.5, xaxis_title='Year-Month', yaxis_title='Age of the API (in days)', xaxis_tickformat = '%d %B (%a)<br>%Y', height=700, width=1300) fig.update_xaxes(showline=True, linewidth=1, linecolor='black', mirror=True) fig.update_yaxes(showline=True, linewidth=1, linecolor='black', mirror=True) fig.show()
解决方案
Plotly完全支持这种自定义颜色需求,核心思路是先对版本字段进行分类,生成对应的颜色映射,再将映射后的颜色值传递给散点的marker参数。具体步骤如下:
1. 提取版本分类信息
从数据集的info_version字段中提取版本前缀和完整子版本:
# 提取版本前缀(如17、18、20) data1['version_prefix'] = data1['info_version'].str.split('.').str[0] # 提取完整子版本(如17.2.3) data1['full_subversion'] = data1['info_version']
2. 创建颜色映射字典
手动指定前缀基础色,再为同前缀下的子版本生成差异化的渐变颜色:
# 为版本前缀指定基础颜色 prefix_color_map = { '17': '#1f77b4', # 蓝色 '18': '#ff7f0e', # 橙色 '20': '#2ca02c' # 绿色 } # 基于基础色调整亮度,生成子版本专属颜色 import matplotlib.colors as mcolors def adjust_lightness(color, amount=0.5): c = mcolors.to_rgb(color) return mcolors.to_hex([max(0, min(1, c[0] + amount)), max(0, min(1, c[1] + amount)), max(0, min(1, c[2] + amount))]) # 为每个子版本分配唯一颜色 subversion_colors = {} for prefix, group in data1.groupby('version_prefix'): base_color = prefix_color_map[prefix] subversions = group['full_subversion'].unique() # 计算亮度调整步长,确保同前缀子版本颜色有区分度 step = 0.2 / len(subversions) for i, sv in enumerate(subversions): subversion_colors[sv] = adjust_lightness(base_color, amount=-0.1 + i*step)
3. 修改散点图的颜色参数
将原散点的颜色参数替换为子版本对应的映射色:
fig.add_trace(go.Scatter(mode='markers', x=data1["commitDate"], y=data1["Days_difference"], marker=dict(color=data1['full_subversion'].map(subversion_colors), size=10), showlegend=False ) )
4. 可选:添加图例说明
若需要展示颜色与版本的对应关系,可手动添加图例项:
# 添加版本前缀的图例 for prefix, color in prefix_color_map.items(): fig.add_trace(go.Scatter( x=[None], y=[None], mode='markers', marker=dict(color=color, size=10), name=f'Version {prefix}.*' )) # 若子版本数量不多,可添加子版本图例(数量过多时建议省略) # for sv, color in subversion_colors.items(): # fig.add_trace(go.Scatter( # x=[None], y=[None], # mode='markers', # marker=dict(color=color, size=10), # name=sv # ))
完整修改后代码
data1= final_api.query("info_title=='Avi CertificateManagementProfile Object API'") data1['commitDate'] = pd.to_datetime(final_api['commitDate']) # 处理版本字段 data1['version_prefix'] = data1['info_version'].str.split('.').str[0] data1['full_subversion'] = data1['info_version'] # 创建颜色映射 prefix_color_map = { '17': '#1f77b4', '18': '#ff7f0e', '20': '#2ca02c' } import matplotlib.colors as mcolors def adjust_lightness(color, amount=0.5): c = mcolors.to_rgb(color) return mcolors.to_hex([max(0, min(1, c[0] + amount)), max(0, min(1, c[1] + amount)), max(0, min(1, c[2] + amount))]) subversion_colors = {} for prefix, group in data1.groupby('version_prefix'): base_color = prefix_color_map[prefix] subversions = group['full_subversion'].unique() step = 0.2 / len(subversions) for i, sv in enumerate(subversions): subversion_colors[sv] = adjust_lightness(base_color, amount=-0.1 + i*step) import plotly.graph_objects as go fig = go.Figure() fig.add_trace(go.Scatter(mode='lines', x=data1["commitDate"], y=data1["Days_difference"], line_color='black', line_width=1, line_shape='vh', showlegend=False ) ) # 修改散点颜色为子版本映射色 fig.add_trace(go.Scatter(mode='markers', x=data1["commitDate"], y=data1["Days_difference"], marker=dict(color=data1['full_subversion'].map(subversion_colors), size=10), showlegend=False ) ) # 添加版本标注 for _,row in data1.iterrows(): fig.add_annotation( go.layout.Annotation( x=row["commitDate"], y=row["Days_difference"], text=row['info_version'], showarrow=False, align='center', yanchor='bottom', yshift=10, textangle=-90) ) # 添加前缀图例 for prefix, color in prefix_color_map.items(): fig.add_trace(go.Scatter( x=[None], y=[None], mode='markers', marker=dict(color=color, size=10), name=f'Version {prefix}.*' )) fig.update_layout(template='plotly_white',title_text='Version Change in Avi CertificateManagementProfile Object API over its Age',title_x=0.5, xaxis_title='Year-Month', yaxis_title='Age of the API (in days)', xaxis_tickformat = '%d %B (%a)<br>%Y', height=700, width=1300) fig.update_xaxes(showline=True, linewidth=1, linecolor='black', mirror=True) fig.update_yaxes(showline=True, linewidth=1, linecolor='black', mirror=True) fig.show()
内容的提问来源于stack exchange,提问作者Brie MerryWeather
相关产品推荐
相关产品推荐

