Plotly:如何使用 For 循环突出显示具有矩形形状的 Pandas 时间序列中的某些时期?

我试图在 Plotly 中突出显示时间段。我似乎最好的方法是使用 Shapes,就像这样,但在现实世界中,您不想像示例 url 中那样手动添加每个形状。我认为 for 循环是最好的解决方案,但欢迎其他(计算量较小的)建议。

我的脚本如下所示:

np.random.seed(12345)

rows = 20

x = pd.Series(np.random.randn(rows),index=pd.date_range('1/1/2020', periods=rows)).cumsum()

df = pd.DataFrame({"index": x})


# add column showing what to shade

df["signal"] = df['index'] < 5


# plot index and highlight periods with Rectangle Shapes in Plotly

fig = px.line(df, x=df.index, y="index")


for row in df.iterrows():

    if df['signal'] == False:

        ply_shapes['shape_' + str(i)]=go.layout.Shape(type="rect",

                                                            x0=df.dato[i-1],

                                                            y0=0,

                                                            x1=df.dato[i],

                                                            y1=2000,

                                                            opacity=0.5,

                                                            layer="below"

                                                        )


lst_shapes=list(ply_shapes.values())

fig.update_layout(shapes=lst_shapes)

fig.show()

但这返回:


ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().


九州编程
浏览 93回答 1
1回答

临摹微笑

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

相关分类

Python