Search code examples
plotlyplotly-dashlinechartplotly-python

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


I'm trying to plot a line chart that differentiates the line color and the line itself(i.e. using a dash or dotted lines) based on a specific condition. The figure isn't showing the lines/change in line color but I could see the change in the color of data points on the plot when I hovered over the chart and also in the legend.

fig = px.line(df2, x=df2['Time_Stamp'], y=df2['Blob_1_Prob_48H'])
count = 0
for j, y in enumerate(df2.Blob_1_Prob_48H):
    if count==0:
        count +=1
        fig.add_traces(go.Scatter(
        x = [df2['Time_Stamp'][j]],
        y = [df2['Blob_1_Prob_48H'][j]],
        mode = "lines+markers",
        name = "48H",                    
        text= df2.Name,
        hovertemplate="Prediction Percentage: %{y}<br>Date &Time: %{x}<br>Name: %{text}<extra></extra>"))
    else:
        if df2['Blob_1_Prob_48H'][j] < df2['Blob_1_Prob_48H'][j-1]:
            fig.add_traces(go.Scatter(
                x = [df2['Time_Stamp'][j]],
                y = [df2['Blob_1_Prob_48H'][j]],
                mode = 'lines',
                name = "48H",    
                line = dict(color='red',width=5, dash='dot'),                
                text= df2.Name,
                hovertemplate="Prediction Percentage: %{y}<br>Date &Time: %{x}<br>Name: %{text}<extra></extra>"))
        
fig.update_layout(title="ALEX(S)",xaxis_title='Date & time',yaxis_title='Blob percentage',yaxis_range=[0,105],showlegend=True,width=1200,
                  height=600)
fig.show()

Image


Solution

  • There are certainly better ways to do this, but here is one code where I separate a list into many increasing and decreasing curves and then plot them with different styles:

    import plotly.graph_objects as go
    import random
    
    xs = [i for i in range(100)]
    ys = [random.randint(1,30) for i in range(100)]
    
    # Temporary lists to store each consecutive increasing or decreasing values
    x_inc = []
    y_inc = []
    x_dec = []
    y_dec = []
    # List to gather all increasing and decreasing curves
    xs_inc = []
    ys_inc = []
    xs_dec = []
    ys_dec = []
    # Indicate if it is the first point of new list
    first_inc = True
    first_dec = True
    # Looping over original values
    for i in range(len(ys)-1):
        if ys[i+1] < ys[i]:
            if first_inc: # If it is the first, add initial point...
                x_dec.append(xs[i])
                y_dec.append(ys[i])
                if y_inc: # ... and add other to list, if not empty
                    xs_inc.append(x_inc)
                    ys_inc.append(y_inc)
            x_dec.append(xs[i+1])
            y_dec.append(ys[i+1])
            first_inc = False
    
            # Restarting all
            x_inc = []
            y_inc = []
            first_dec = True
        else:
            if first_dec: # If it is the first, add initial point...
                x_inc.append(xs[i])
                y_inc.append(ys[i])
                if y_dec: # ... and add other to list, if not empty
                    xs_dec.append(x_dec)
                    ys_dec.append(y_dec)
            x_inc.append(xs[i+1])
            y_inc.append(ys[i+1])
            first_dec = False
    
            # Restarting all
            x_dec = []
            y_dec = []
            first_inc = True
    
    fig = go.Figure()
    
    # Plotting all increasing curves
    for i, (x, y) in enumerate(zip(xs_inc,ys_inc)):
        fig.add_trace(go.Scatter(x=x,
                                y=y, 
                                name = 'Increase',
                                legendgroup = 'increase', # Group them together
                                showlegend=(True if i == 0 else False), # Only add legend to the first
                                line = dict(color='blue',width=3, dash='dash'),
                                mode="lines",
                                ))
    # Plotting all decreasing curves
    for i, (x, y) in enumerate(zip(xs_dec,ys_dec)):
        fig.add_trace(go.Scatter(x=x,
                                y=y, 
                                name = 'Decrease',
                                legendgroup = 'decrease', # Group them together
                                showlegend=(True if i == 0 else False), # Only add legend to the first
                                line = dict(color='red',width=3, dash='dot'),
                                mode="lines",
                                ))
    
    fig.show()
    

    Output: decreasing and increasing curves

    If you have large amount of numbers, you should adapt to numpy or pandas, for example.