1 回答
TA贡献1982条经验 获得超2个赞
您的代码片段无法工作的原因有多种。
1. iterrows()
返回一个迭代器,其中包含每行的索引和每行中的数据作为seres。要使用它,您必须替换
for row in df.iterrows(): if df['signal'] == False:
与(例如):
for row in df.iterrows(): if row[1]['signal'] == True:
引发您的错误是因为您分配了一系列with而True, False
不是if df['signal'] == False:
像if row[1]['signal'
将做的那样分配单个值。
但仅仅解决这个问题并不能帮助你。至少不在您的代码片段的范围内,因为:
2. dato
您的示例数据框中不存在。
类似的问题之前已经被问过并回答过。但由于对于听起来非常不同的问题,解决方案是相似的,因此我决定也为您的用例制定一个自定义解决方案。
在这两种情况下,最好的方法在很大程度上取决于您如何在时间序列中识别和分配突出显示的时间段。以下示例将使用随机数据并根据阈值识别要突出显示的时间段。就像你的问题一样。
我的建议将归结为一个函数,highLights()
该函数将一个绘图图、一个 pandas 系列和一个阈值作为输入,以及一些其他细节(看看文档字符串)。
highLights()
具有一些示例输入的函数:
fig = highLights(fig = fig, variable = 'signal', level = 5, mode = 'above', fillcolor = 'rgba(200,0,200,0.2)', layer = 'below')
阴谋
完整代码:
# imports
import numpy as np
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
import datetime
pd.set_option('display.max_rows', None)
# data sample
cols = ['signal']
nperiods = 200
np.random.seed(123)
df = pd.DataFrame(np.random.randint(-10, 12, size=(nperiods, len(cols))),
columns=cols)
datelist = pd.date_range(datetime.datetime(2020, 1, 1).strftime('%Y-%m-%d'),periods=nperiods).tolist()
df['dato'] = datelist
df = df.set_index(['dato'])
df.index = pd.to_datetime(df.index)
df.iloc[0] = 0
df = df.cumsum().reset_index()
# plotly setup
fig = px.line(df, x='dato', y=df.columns[1:])
fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='rgba(0,0,255,0.1)')
fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor='rgba(0,0,255,0.1)')
# function to set background color for a
# specified variable and a specified level
def highLights(fig, variable, level, mode, fillcolor, layer):
"""
Set a specified color as background for given
levels of a specified variable using a shape.
Keyword arguments:
==================
fig -- plotly figure
variable -- column name in a pandas dataframe
level -- int or float
mode -- set threshold above or below
fillcolor -- any color type that plotly can handle
layer -- position of shape in plotly fiugre, like "below"
"""
if mode == 'above':
m = df[variable].gt(level)
if mode == 'below':
m = df[variable].lt(level)
df1 = df[m].groupby((~m).cumsum())['dato'].agg(['first','last'])
for index, row in df1.iterrows():
#print(row['first'], row['last'])
fig.add_shape(type="rect",
xref="x",
yref="paper",
x0=row['first'],
y0=0,
x1=row['last'],
y1=1,
line=dict(color="rgba(0,0,0,0)",width=3,),
fillcolor=fillcolor,
layer=layer)
return(fig)
fig = highLights(fig = fig, variable = 'signal', level = 5, mode = 'above',
fillcolor = 'rgba(200,0,200,0.2)', layer = 'below')
fig.update_layout(template = 'plotly_dark')
fig.show()
添加回答
举报