Plotly:如何根据条件为两条线之间的填充着色?

Pat*_*ler 14 python charts fill plotly plotly-python

我想在绘图图表上的黑色和蓝色线之间添加填充颜色。我知道这可以通过 Plotly 完成,但我不确定如何根据条件用两种颜色填充图表。这是我的 Plotly 图表这就是我想要实现的目标

蓝色背景的图表是我的 Plotly 图表。我想让它看起来像白色背景的图表。(忽略白色图表上的红色和绿色条)

我希望它通过的条件是:

如果黑线位于蓝线上方,则将两条线之间的区域填充为绿色。

如果黑线位于蓝线下方,则将两条线之间的区域填充为红色。

这如何用 Plotly 来完成呢?如果 Plotly 无法做到这一点,可以使用其他与 Python 配合使用的绘图工具来完成。

ves*_*and 18

由于多种原因(如果您感兴趣,我愿意进一步解释),最好的方法似乎是go.Figure()每次平均值交叉时向对象添加两条迹线,然后定义fill='tonexty'第二次使用的填充跟踪使用:

for df in dfs:
    fig.add_traces(go.Scatter(x=df.index, y = df.ma1,
                              line = dict(color='rgba(0,0,0,0)')))
    
    fig.add_traces(go.Scatter(x=df.index, y = df.ma2,
                              line = dict(color='rgba(0,0,0,0)'),
                              fill='tonexty', 
                              fillcolor = fillcol(df['label'].iloc[0])))
Run Code Online (Sandbox Code Playgroud)

fillcol是一个简单的自定义函数,如下面的完整代码片段所示。我使用了如何在每次列中的字符串值发生变化时分割数据帧?中描述的方法。每次平均值相互交叉时,在数据框中产生必要的分割。

阴谋

在此输入图像描述

完整代码:

import plotly.graph_objects as go
import numpy as np

import pandas as pd
from datetime import datetime
pd.options.plotting.backend = "plotly"

# sample data
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
df.index = df.Date
df = df[['AAPL.Close', 'mavg']]
df['mavg2'] = df['AAPL.Close'].rolling(window=50).mean()
df.columns = ['y', 'ma1', 'ma2']
df=df.tail(250).dropna()
df1 = df.copy()

# split data into chunks where averages cross each other
df['label'] = np.where(df['ma1']>df['ma2'], 1, 0)
df['group'] = df['label'].ne(df['label'].shift()).cumsum()
df = df.groupby('group')
dfs = []
for name, data in df:
    dfs.append(data)

# custom function to set fill color
def fillcol(label):
    if label >= 1:
        return 'rgba(0,250,0,0.4)'
    else:
        return 'rgba(250,0,0,0.4)'

fig = go.Figure()

for df in dfs:
    fig.add_traces(go.Scatter(x=df.index, y = df.ma1,
                              line = dict(color='rgba(0,0,0,0)')))
    
    fig.add_traces(go.Scatter(x=df.index, y = df.ma2,
                              line = dict(color='rgba(0,0,0,0)'),
                              fill='tonexty', 
                              fillcolor = fillcol(df['label'].iloc[0])))

# include averages
fig.add_traces(go.Scatter(x=df1.index, y = df1.ma1,
                          line = dict(color = 'blue', width=1)))

fig.add_traces(go.Scatter(x=df1.index, y = df1.ma2,
                          line = dict(color = 'red', width=1)))

# include main time-series
fig.add_traces(go.Scatter(x=df1.index, y = df1.y,
                          line = dict(color = 'black', width=2)))

fig.update_layout(showlegend=False)
fig.show()
Run Code Online (Sandbox Code Playgroud)