[英]Plotly: change line color on line crossings
I have a dataframe with two data series and a date.我有一个包含两个数据系列和一个日期的数据框。 I want to plot it and change the line colors when the data series are crossing.
我想绘制它并在数据系列交叉时更改线条颜色。
import plotly.graph_objects as go
from plotly.subplots import make_subplots
data = {'Date': ['1.1.2020', '2.1.2020', '3.1.2020', '4.1.2020', '5.1.2020'],
'S1': [20, 21, 19, 18, 20],
'S2': [10, 11, 30, 18, 10]}
df = pd.DataFrame(data)
df['color']= df.apply(lambda row: 'black' if row['S1'] >= row['S2'] else 'red', axis=1)
fig = make_subplots(rows=1, cols=1,
vertical_spacing=0.05,
shared_xaxes=True)
fig.add_trace(go.Scatter(
x=df['Date'],
y=df['S1'],
line=dict(color='blue')),
row=1, col=1)
fig.add_trace(go.Scatter(
x=df['Date'],
y=df['S2'],
line=dict(color=list(df['color']))),
row=1, col=1)
fig.show()
This is how it should look:它应该是这样的:
Yet, the code does not work.
然而,代码不起作用。 Any hints?
有什么提示吗?
Edit to increase solution space: It can also look like that编辑以增加解决方案空间:它也可以看起来像这样
2
2
@Lemon: if I run your proposed solution using that data set @Lemon:如果我使用该数据集运行您提出的解决方案
data = {'Date': ['1.1.2020', '2.1.2020', '3.1.2020', '4.1.2020', '5.1.2020', '6.1.2020', '7.1.2020', '8.1.2020', '9.1.2020', '10.1.2020'],
'S1': [20, 21, 19, 18, 20, 19, 18, 20, 20, 20],
'S2': [10, 11, 30, 18, 10, 10, 17, 30, 20, 10]}
I will get the following result.我会得到以下结果。 I have not figured out a way to remove the red line between the crossings.
我还没有想出一种方法来消除交叉口之间的红线。 Any hints?
有什么提示吗?
Working Solution工作解决方案
based on lemons suggestion, here is the solution, that works for me基于柠檬的建议,这是对我有用的解决方案
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd
data = {'Date': ['1.1.2020', '2.1.2020', '3.1.2020', '4.1.2020',
'5.1.2020', '6.1.2020', '7.1.2020', '8.1.2020', '9.1.2020',
'10.1.2020'],
'S1': [20, 21, 19, 18, 20, 19, 18, 20, 20, 20],
'S2': [10, 11, 30, 18, 10, 10, 17, 30, 20, 10]}
df = pd.DataFrame(data)
df['crossing']= df.loc[(df.S1 < df.S2) | (df.S1.shift(1) <
df.S2.shift(1)) | (df.S1.shift(-1) < df.S2.shift(-1)), 'S2']
fig = go.Figure()
fig.add_trace(go.Scatter(
x=df['Date'],
y=df['S1'],
line=dict(color='blue')))
fig.add_trace(go.Scatter(
x=df['Date'],
y=df['S2'],
line=dict(color='black')))
fig.add_trace(go.Scatter(
x=df['Date'],
y=df['crossing'],
line=dict(color='red')))
fig.show()
Resulting chart结果图表
My initial idea followed the same r-beginners's idea, though what you can do to have a longer red line is detecting the rows when S2>S1 and a range of (-1, 1) centered on your " S2>S1 " rows, using:我最初的想法遵循了同样的 r-beginners 的想法,虽然你可以做一个更长的红线是检测当 S2>S1 和 (-1, 1) 范围以你的“ S2>S1 ”行为中心时的行,使用:
df.loc[(df.S1 < df.S2) |
(df.S1.shift(1) < df.S2.shift(1)) |
(df.S1.shift(-1) < df.S2.shift(-1)), <the field you want to select>]
Final code should look like:最终代码应如下所示:
import plotly.graph_objects as go
from plotly.subplots import make_subplots
data = {'Date': ['1.1.2020', '2.1.2020', '3.1.2020', '4.1.2020', '5.1.2020'],
'S1': [20, 21, 19, 18, 20],
'S2': [10, 11, 30, 18, 10]}
df = pd.DataFrame(data)
df['color']= df.apply(lambda row: 'black' if row['S1'] >= row['S2'] else 'red', axis=1)
fig = make_subplots(rows=1, cols=1,
vertical_spacing=0.05,
shared_xaxes=True)
fig.add_trace(go.Scatter(
x=df['Date'],
y=df['S1'],
line=dict(color='blue')),
row=1, col=1)
fig.add_trace(go.Scatter(
x=df['Date'],
y=df['S2'],
line=dict(color='black')),
row=1, col=1)
fig.add_trace(go.Scatter(
x=df.loc[(df.S1 < df.S2) | (df.S1.shift(1) < df.S2.shift(1)) | (df.S1.shift(-1) < df.S2.shift(-1)), 'Date'],
y=df.loc[(df.S1 < df.S2) | (df.S1.shift(1) < df.S2.shift(1)) | (df.S1.shift(-1) < df.S2.shift(-1)), 'S2'],
line=dict(color='red')),
row=1, col=1)
fig.show()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.