Search code examples
plotlyscatter

Plotly: scatter conditional color formatting issues


Any idea why the conditional color formatting isn't working here when the mode = 'lines' is activated ?

import plotly.offline as py
import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot, plot
from plotly import tools
import pandas as pd
import numpy
init_notebook_mode(connected=True)

data = [
    [1, 0.5, True],
    [2, 0.7, True],
    [3, -0.1, False],
    [4, -0.3, False],
    [5, -0.5, False],
]

df = pd.DataFrame(
    data,
    columns=['x', 'y', 'Above 0']
)

trace = go.Scatter(
    x=df['x'],
    y=df['y'],
    #mode='markers',  
    mode='lines',     #<---  ISSUE HERE. #########################################
    marker=dict(
        # I want the color to be green if 
        # lower_limit ≤ y ≤ upper_limit
        # else red
        color=np.where(df['Above 0'], 'green', 'red'),
    )
)


iplot([trace])

The final idea is to plot an oscilliator arround 0 that forward fill green above 0 and red below 0.

Like so: enter image description here


Solution

  • import pandas as pd
    import numpy as np
    import plotly.graph_objects as go
    import plotly.express as px
    
    data = [
        [1, 0.5, True],
        [2, 0.7, True],
        [3, -0.1, False],
        [4, -0.3, False],
        [5, -0.5, False],
    ]
    
    df = pd.DataFrame(data, columns=["x", "y", "Above 0"])
    
    # interpolate out line so that when it goes across y=0 gap is minimised
    xn = np.linspace(df["x"].min(), df["x"].max(), len(df) * 25)
    df2 = pd.DataFrame({"x": xn, "y": np.interp(xn, df["x"], df["y"])})
    
    px.line(
        df2,
        x="x",
        y="y",
        color=df2["y"] > 0,
        color_discrete_map={True: "green", False: "red"},
    ).update_traces(fill="tozeroy", showlegend=False)
    

    enter image description here