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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 20:55:09