Hi! i want to fill an area based on y values: red to negative, green to positives. How can i do that?
I donβt know how to it with one single trace, but here is a solution using numpy masks:
import plotly.graph_objects as go
import numpy as np
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
mask = y >= 0
fig = go.Figure(go.Scatter(x=x[mask], y=np.sin(x)[mask], mode='lines',
fill='tozeroy', fillcolor='green'))
fig.add_trace(go.Scatter(x=x[~mask], y=y[~mask], mode='lines', fill='tozeroy', fillcolor='red'))
fig.show()
Thank you for your answer! But i want to do it with a single trace
I donβt think you can. That would be a new mode for the fill
argument of Scatter
traces.
Ok, thanks for your help!!!
@yuricda96 If your usecase of having only one trace is so that the legend behaves as a single trace, you can do the following:
- Hide the legend for one of the two traces
showlegend=False
- Put both traces in the same legend group (e.g.
legendgroup="my-trace"
)
This way you will only see one trace for the two and clicking on the legend shows/hides both traces at once.
You can also set the line color and fillcolor differently to have continuity of the line with different fill colors if necessary.
Hope this can be of help.
Iβll just add this here, Fill area between 2 lines [SOLVED]
This saved me from a great deal of frustration.
Great tips, I like it
However, it has some issues when the values are equal to the threshold (zero in your example).
so it has a gaped space with no color.
and if the steps are few it will be bigger and awful plot .
So I tried to solve this and get this maybe someone needs it (like me a few hours ago)
import plotly.graph_objects as go
import numpy as np
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
# I just add a threshold
threshold= 0
x2=[]
y2=[]
for i in range(len(y)-1):
x2 +=[x[i]]
y2 +=[y[i]]
if y[i]>threshold>y[i+1] or y[i]<threshold<y[i+1]:
Xi=x[i]+((threshold-y[i])*(x[i+1]-x[i])/(y[i+1]-y[i]))
x2 +=[Xi]
y2 +=[threshold]
x2 +=[x[-1]]
y2 +=[y[-1]]
x2 = np.array(x2)
y2 = np.array(y2)
mask = y2 >= threshold
mask2 = y2 <= threshold
fig = go.Figure(go.Scatter(x=x2[mask], y=np.sin(x2)[mask], mode='lines',
fill='tozeroy', fillcolor='green'))
fig.add_trace(go.Scatter(x=x2[mask2], y=y2[mask2], mode='lines', fill='tozeroy', fillcolor='red'))
fig.show()
and it works
you can set the threshold as you wish (0.2)
All my best