在不使用 Plotly Express 的情况下向 Plotly 子图添加垂直矩形

Posted

技术标签:

【中文标题】在不使用 Plotly Express 的情况下向 Plotly 子图添加垂直矩形【英文标题】:Adding Vertical Rectangles to Plotly Subplots Without Using Plotly Express 【发布时间】:2021-03-04 11:36:51 【问题描述】:

我正在尝试在具有子图的绘图图中创建与不同日期范围相对应的阴影区域。

理想情况下,我希望每个阴影矩形都适合每个子图,但我发现这很困难。下面是一些示例代码:

import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots

df = pd.DataFrame('A': list(range(25)),
                   'B': list(range(25, 50)),
                   'C': list(range(50, 75)), index=pd.date_range('20200101', periods=25))

fig = make_subplots(rows=3, cols=1)

for idx, col in enumerate(df.columns):
    fig.add_trace(go.Scatter(x=df.index, y=df[col]), row=idx + 1, col=1)

shape_dict = 'type':'rect', 'xref':'x', 'yref':'paper', 'x0':'2020-01-03', 'x1':'2020-01-12', 'y0':0, 'y1':1, 'fillcolor': 'LightSalmon', 'layer': 'below', 'opacity': 0.25, 'line_width': 0

如果我做fig.update_layout(shapes=[shape_dict]),那么我会得到这个:

还不错,但我更希望将这些形状中的每一个单独安装到它们自己的子图中。

当我尝试使用 add_shape 执行此操作时,阴影区域失去了缩放:

for idx, col in enumerate(df.columns):
    fig.add_trace(go.Scatter(x=df.index, y=df[col]), row=idx + 1, col=1)
    fig.add_shape(shape_dict, row=idx + 1, col=1)

这给了我这个:

我希望不得不单独重新计算坐标轴。

我也无法访问add_vrect——我不知道为什么,但它不能作为一种方法使用,我也无法使用plotly.express,而且大部分 plot.ly 的文档都使用px 图表及其实现我所描述的方法。

编辑

要回复下面的答案,add_vrect 不适用于我的 plotly 版本,即 4.12.0。

例如r-beginners 中的示例代码返回给我:

df = pd.DataFrame('A': list(range(25)),
                   'B': list(range(25, 50)),
                   'C': list(range(50, 75)), index=pd.date_range('20200101', periods=25))

fig = make_subplots(rows=3, cols=1)

for idx, col in enumerate(df.columns):
    fig.add_trace(go.Scatter(x=df.index, y=df[col]), row=idx + 1, col=1)

# shape_dict = 'type':'rect', 'xref':'x', 'yref':'paper', 'x0':'2020-01-03', 'x1':'2020-01-12', 'y0':0, 'y1':1, 'fillcolor': 'LightSalmon', 'layer': 'below', 'opacity': 0.25, 'line_width': 0
# fig.update_layout(shapes=[shape_dict])

fig.add_vrect(
    x0="2020-01-03", x1="2020-01-12",
    y0=0, y1=1,
    fillcolor="LightSalmon", opacity=0.25,
    layer="below", line_width=0)

fig.show()

返回错误信息:AttributeError: 'Figure' object has no attribute 'add_vrect'

【问题讨论】:

【参考方案1】:

阴影以add_vrect() 输出到每个子图。规模也不受影响。此答案是否符合您的问题意图?

import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots

df = pd.DataFrame('A': list(range(25)),
                   'B': list(range(25, 50)),
                   'C': list(range(50, 75)), index=pd.date_range('20200101', periods=25))

fig = make_subplots(rows=3, cols=1)

for idx, col in enumerate(df.columns):
    fig.add_trace(go.Scatter(x=df.index, y=df[col]), row=idx + 1, col=1)

# shape_dict = 'type':'rect', 'xref':'x', 'yref':'paper', 'x0':'2020-01-03', 'x1':'2020-01-12', 'y0':0, 'y1':1, 'fillcolor': 'LightSalmon', 'layer': 'below', 'opacity': 0.25, 'line_width': 0
# fig.update_layout(shapes=[shape_dict])

fig.add_vrect(
    x0="2020-01-03", x1="2020-01-12",
    y0=0, y1=1,
    fillcolor="LightSalmon", opacity=0.25,
    layer="below", line_width=0,
)

fig.show()

【讨论】:

我正在使用 plot.ly 4.12.0 版,我无法访问 add_vrect。复制并粘贴您提供的代码返回了 AttributeError 我的环境也是plotly 4.12.0和python 3.6.3。我刚刚注释掉了你的一些代码并添加了fig.add_vrect()。您看到什么属性错误? 表示fig没有属性add_vrect 你复制了我的整个代码吗?库是否已同时导入 px 和 go? @r-beginners 复制并粘贴您的代码给出:AttributeError: 'Figure' object has no attribute 'add_vrect'【参考方案2】:

我无法发表评论,因此将其发布为(潜在的)答案。

您是否在 Jupyter 中使用它?如果是这样,是否也更新了 plotly 的 jupyterlab-plotly 扩展名?如果没有,这可能解释了为什么您无法访问 add_vrect 方法。我认为 jupyterlab 扩展主要负责渲染,但它仍然可能会抛出找不到方法的错误。 检查/更新的最快方法是jupyter labextension update --all

【讨论】:

以上是关于在不使用 Plotly Express 的情况下向 Plotly 子图添加垂直矩形的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用移动网络的情况下向自己发送假短信?

如何在不使用 HTML 的情况下向 JLabel 添加换行符

如何让机器人在不使用命令的情况下向特定频道中的特定公会发送消息

是否可以在不启动核心定位的情况下向用户询问当前位置

在不干扰平移的情况下向 MKMapView 添加左滑动手势

如何在不覆盖的情况下向 Firebase Firestore 添加值?