Plotly:如何在指定阈值的折线图上显示不同的颜色段?

Plotly: How to display different color segments on a line chart for specified thresholds?

我有一个 multi-line 图表显示随时间增加的百分比。我想在我的代码中设置一个阈值以具有上限和下限。如果线落在这些界限之外,我希望折线图的特定部分的颜色与其 parent.

不同

这就是我在做的事情:

import plotly.express as px
import plotly.graph_objects as go



fig = px.line(df14, x = "Date", y = "Percent", color = "id", 
          title = "id Growth in Percentage (US)", 
          labels = {"Percent": "Percent Growth"})

fig.update_layout(
font_family="Arial",
font_color="black",
title_font_family="Arial",
title_font_color="black",
legend_title_font_color="black"                                           #style the text (legend, title etc)
)


fig.update_xaxes(title_font_family="Arial")                               #style ance center title
fig.update_layout(
title={
    'text': "id Growth Percentage in US (Line Graph)",
    'y':0.9,
    'x':0.5,
    'xanchor': 'center',
    'yanchor': 'top'})


fig.update_traces(mode='markers+lines')                                    #add dots to line

fig.show()

这是视觉结果:

让我放大一行来更好地解释:

我想为每个 id设置一个阈值,并且如果线超过或低于这个阈值,那部分的颜色将会不同线 图。例如:

id IAA 的上限可能是 5,IAA 的下限可能是 0。 任何大于 5 或​​小于 0 的值都以特定颜色突出显示。

id SSS 的上限可能是 10,SSS 的下限可能是 3 任何大于 10 或小于 3 的值都应以特定颜色突出显示。

我希望阈值适用于每个 id

请看下面:

线条中突出显示的黄色部分反映了折线图超过或降低了设定阈值的位置。使用 Plotly 可以做到这一点吗?

这里是原始数据示例: 更新:

    id       Start      End         Diff        Percent     Date        
    IAA     4/1/2019    5/1/2019    160.4279    11.10809    04-01-2019 to 05-01-2019
    IAA 5/1/2019    6/1/2019    136.0248    8.476798    05-01-2019 to 06-01-2019
    IAA     6/1/2019    7/1/2019    174.0513    9.998946    06-01-2019 to 07-01-2019
    IAA     7/1/2019    8/1/2019    112.0424    5.851551    07-01-2019 to 08-01-2019
    IAA     8/1/2019    9/1/2019    141.8488    6.998691    08-01-2019 to 09-01-2019
    IAA     9/1/2019    10/1/2019   103.5522    4.774984    09-01-2019 to 10-01-2019
    IAA     10/1/2019   11/1/2019   125.6087    5.528085    10-01-2019 to 11-01-2019
    IAA     11/1/2019   12/1/2019   145.2591    6.058016    11-01-2019 to 12-01-2019
    IAA     12/1/2019   1/1/2020    115.5121    4.542251    12-01-2019 to 01-01-2020
    IAA     1/1/2020    2/1/2020    185.7191    6.985673    01-01-2020 to 02-01-2020
    IAA     2/1/2020    3/1/2020    126.7386    4.455896    02-01-2020 to 03-01-2020
    IAA     3/1/2020    4/1/2020    231.3461    7.786734    03-01-2020 to 04-01-2020
    IAA     4/1/2020    5/1/2020    97.02587      3.02981   04-01-2020 to 05-01-2020
    IAA     5/1/2020    6/1/2020    42.85235      1.298792  05-01-2020 to 06-01-2020
    IAA     6/1/2020    7/1/2020    124.666    3.729997     06-01-2020 to 07-01-2020
    IAA     7/1/2020    8/1/2020    357.9974    10.32609    07-01-2020 to 08-01-2020
    IAA     8/1/2020    9/1/2020    490.9587      12.8358   08-01-2020 to 09-01-2020
    IAA     9/1/2020    10/1/2020   204.5478    4.739428    09-01-2020 to 10-01-2020
    IAA     10/1/2020   11/1/2020   287.6025    6.362292    10-01-2020 to 11-01-2020
   SSStest  4/1/2019    5/1/2019    12.38486    5.780551    04-01-2019 to 05-01-2019
   SSStest  5/1/2019    6/1/2019    -2.61735    -1.15487    05-01-2019 to 06-01-2019
   SSStest  6/1/2019    7/1/2019    -5.6187    -2.50814     06-01-2019 to 07-01-2019
   SSStest  7/1/2019    8/1/2019    3.204252    1.467153    07-01-2019 to 08-01-2019
   SSStest  8/1/2019    9/1/2019    -25.3782    -11.4521    08-01-2019 to 09-01-2019
   SSStest  9/1/2019    10/1/2019   -10.9717    -5.59137    09-01-2019 to 10-01-2019

如有任何建议,我们将不胜感激

更新

有没有办法让整行显示标记点? 我试过这个:mode = 'markers+lines' 但没有得到想要的结果:

**Update, I have figured this out:** 
fig.update_traces(mode='markers+lines')    

更新问题:

此外,有没有办法在此处的悬停注释上添加日期和百分比标题?。我正在研究 Plotly 文档。

[![在此处输入图片描述][4]][4]

我提出了一个建议,应该完全符合您的要求。下图是由下面的代码示例生成的。该代码使用一个字典,其中包含不同 PODs 的不同上限和下限,以及为不同 pods:

设置不同颜色的可能性
lim = {'IAD': {'lower': 90,'upper': 350, 'color':'yellow'},
       'SJCtest': {'lower': 10,'upper': 12, 'color':'green'}}

情节

我很想先过滤你的数据框,然后根据它向图中添加新的轨迹。但我的解决方案实际上遍历每条轨迹的每个数据点,并根据上面的字典为这些点着色。所以不需要任何数据处理。看一看,运行 一些测试,然后让我知道结果如何。

完整代码

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go

df = pd.DataFrame({'POD': {0: 'IAD',
                          1: 'IAD',
                          2: 'IAD',
                          3: 'IAD',
                          4: 'IAD',
                          5: 'IAD',
                          6: 'IAD',
                          7: 'IAD',
                          8: 'IAD',
                          9: 'IAD',
                          10: 'IAD',
                          11: 'IAD',
                          12: 'IAD',
                          13: 'IAD',
                          14: 'IAD',
                          15: 'IAD',
                          16: 'IAD',
                          17: 'IAD',
                          18: 'IAD',
                          19: 'SJCtest',
                          20: 'SJCtest',
                          21: 'SJCtest',
                          22: 'SJCtest',
                          23: 'SJCtest',
                          24: 'SJCtest'},
                         'Start': {0: '4/1/2019',
                          1: '5/1/2019',
                          2: '6/1/2019',
                          3: '7/1/2019',
                          4: '8/1/2019',
                          5: '9/1/2019',
                          6: '10/1/2019',
                          7: '11/1/2019',
                          8: '12/1/2019',
                          9: '1/1/2020',
                          10: '2/1/2020',
                          11: '3/1/2020',
                          12: '4/1/2020',
                          13: '5/1/2020',
                          14: '6/1/2020',
                          15: '7/1/2020',
                          16: '8/1/2020',
                          17: '9/1/2020',
                          18: '10/1/2020',
                          19: '4/1/2019',
                          20: '5/1/2019',
                          21: '6/1/2019',
                          22: '7/1/2019',
                          23: '8/1/2019',
                          24: '9/1/2019'},
                         'End': {0: '5/1/2019',
                          1: '6/1/2019',
                          2: '7/1/2019',
                          3: '8/1/2019',
                          4: '9/1/2019',
                          5: '10/1/2019',
                          6: '11/1/2019',
                          7: '12/1/2019',
                          8: '1/1/2020',
                          9: '2/1/2020',
                          10: '3/1/2020',
                          11: '4/1/2020',
                          12: '5/1/2020',
                          13: '6/1/2020',
                          14: '7/1/2020',
                          15: '8/1/2020',
                          16: '9/1/2020',
                          17: '10/1/2020',
                          18: '11/1/2020',
                          19: '5/1/2019',
                          20: '6/1/2019',
                          21: '7/1/2019',
                          22: '8/1/2019',
                          23: '9/1/2019',
                          24: '10/1/2019'},
                         'Diff': {0: 160.4279,
                          1: 136.0248,
                          2: 174.0513,
                          3: 112.0424,
                          4: 141.8488,
                          5: 103.5522,
                          6: 125.6087,
                          7: 145.2591,
                          8: 115.5121,
                          9: 185.7191,
                          10: 126.7386,
                          11: 231.3461,
                          12: 97.02587,
                          13: 42.85235,
                          14: 124.666,
                          15: 357.9974,
                          16: 490.9587,
                          17: 204.5478,
                          18: 287.6025,
                          19: 12.38486,
                          20: -2.61735,
                          21: -5.6187,
                          22: 3.204252,
                          23: -25.3782,
                          24: -10.9717},
                         'Percent': {0: 11.108089999999999,
                          1: 8.476797999999999,
                          2: 9.998946,
                          3: 5.851551000000001,
                          4: 6.998691,
                          5: 4.774984,
                          6: 5.528085,
                          7: 6.058016,
                          8: 4.542251,
                          9: 6.985672999999999,
                          10: 4.455896,
                          11: 7.786734,
                          12: 3.02981,
                          13: 1.298792,
                          14: 3.729997,
                          15: 10.326089999999999,
                          16: 12.8358,
                          17: 4.739428,
                          18: 6.362292,
                          19: 5.780551,
                          20: -1.15487,
                          21: -2.50814,
                          22: 1.4671530000000002,
                          23: -11.4521,
                          24: -5.5913699999999995},
                         'Date': {0: '04-01-2019 to 05-01-2019',
                          1: '05-01-2019 to 06-01-2019',
                          2: '06-01-2019 to 07-01-2019',
                          3: '07-01-2019 to 08-01-2019',
                          4: '08-01-2019 to 09-01-2019',
                          5: '09-01-2019 to 10-01-2019',
                          6: '10-01-2019 to 11-01-2019',
                          7: '11-01-2019 to 12-01-2019',
                          8: '12-01-2019 to 01-01-2020',
                          9: '01-01-2020 to 02-01-2020',
                          10: '02-01-2020 to 03-01-2020',
                          11: '03-01-2020 to 04-01-2020',
                          12: '04-01-2020 to 05-01-2020',
                          13: '05-01-2020 to 06-01-2020',
                          14: '06-01-2020 to 07-01-2020',
                          15: '07-01-2020 to 08-01-2020',
                          16: '08-01-2020 to 09-01-2020',
                          17: '09-01-2020 to 10-01-2020',
                          18: '10-01-2020 to 11-01-2020',
                          19: '04-01-2019 to 05-01-2019',
                          20: '05-01-2019 to 06-01-2019',
                          21: '06-01-2019 to 07-01-2019',
                          22: '07-01-2019 to 08-01-2019',
                          23: '08-01-2019 to 09-01-2019',
                          24: '09-01-2019 to 10-01-2019'}})

fig = px.line(df, x="Date", y="Diff", color = 'POD')

import plotly.graph_objects as go
included = 0

lim = {'IAD': {'lower': 90,'upper': 350, 'color':'yellow'},
       'SJCtest': {'lower': 10,'upper': 12, 'color':'green'}}

for i, d in enumerate(fig.data):
    for j, y in enumerate(d.y):
        if y < lim[d.name]['lower'] or y > lim[d.name]['upper']:
             
             if j == 0:
                fig.add_traces(go.Scatter(x=[fig.data[i]['x'][j]],
                                          y=[fig.data[i]['y'][j]],
                                          mode = 'markers',
                                          marker = dict(color=lim[d.name]['color']),
                                          name = d.name + ' threshold',
                                          legendgroup = d.name + ' threshold'))
                included = included + 1
             else:
                fig.add_traces(go.Scatter(x=[fig.data[i]['x'][j-1], fig.data[i]['x'][j]],
                                          y=[fig.data[i]['y'][j-1], fig.data[i]['y'][j]],
                                          mode = 'lines',
                                          # marker = dict(color='yellow'),
                                          line = dict(width = 6, color = lim[d.name]['color']),
                                          name = d.name + ' threshold',
                                          legendgroup = d.name + ' threshold',
                                          showlegend = False if included > 0 else True,
                                         ))
                included = included + 1
            
fig.show()