Plotly:如何在子图中制作一条无界垂直线?

6

目标是在每个子图中在x=1处获得垂直无限线。 在此示例中,我将在第一行,第一列中尝试单个plotly形状的type="line"。

from plotly.subplots import make_subplots
import plotly.graph_objects as go
import numpy as np


fig = make_subplots(
    rows=2,
    cols=2,
    subplot_titles=list(map(str, range(4))),
    shared_xaxes=True,
    shared_yaxes=False,
)

time = np.linspace(-np.pi, np.pi, 1000)

for i in range(4):
    data = np.sin((i+1) * time)
    fig.add_trace(
        go.Scatter(y=data,x=time, name=str(i)),
        row=1 if i in [0, 1] else 2,
        col=1 if i in [0, 2] else 2,
    )

fig.add_shape(
    go.layout.Shape(
        type="line",
        yref="paper",
        xref="x",
        x0=1,
        y0=0,
        x1=1,
        y1=1,
        line=dict(color="RoyalBlue", width=3),
    ),row=1,col=1)

fig.write_image("1.png",width=800, height=600, scale=1)

Plot1

看起来是通过行和列添加形状覆盖了yref和xref属性,返回的是一条线段而不是无限线。在打印之前将yref强制设为"paper" ...

for shape in fig.layout.shapes:
    shape["yref"]="paper"

我得到了这个: Plot2

这可能更糟,这是相对于整个图而不是子图y轴的线。有人遇到过这个问题吗?有什么想法吗?

2个回答

6

这是您期望的情节吗?

enter image description here

如果是这种情况,那么您需要为每个由位置 row=i,col=j 定义的子图插入一个形状。以下代码片段将为您完成此操作。如果更改子图的总数,则只需对行和列的数量进行一些监督,以了解网格的外观。
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import numpy as np


fig = make_subplots(
    rows=2,
    cols=2,
    subplot_titles=list(map(str, range(4))),
    shared_xaxes=True,
    shared_yaxes=False,
)

time = np.linspace(-np.pi, np.pi, 1000)

for i in range(4):
    data = np.sin((i+1) * time)
    fig.add_trace(
        go.Scatter(y=data,x=time, name=str(i)),
        row=1 if i in [0, 1] else 2,
        col=1 if i in [0, 2] else 2,
    )

colors = ['blue', 'firebrick', 'green', 'purple']
rows = 2
cols = 2

# add traces
counter=0 # for colors
for i in range(1,3):
    for j in range(1,3):
        fig.add_shape(go.layout.Shape(type="line",
                                        yref="paper",
                                        xref="x",
                                        x0=1,
                                        y0=-2,
                                        x1=1,
                                        y1=2,
                                        #line=dict(color="RoyalBlue", width=3),),
                                        line=dict(color=colors[counter], width=3),),
                      row=i,
                      col=j)
        counter = counter + 1

fig.show()

评论后编辑:

据我所知,您无法直接定义一个无界限制。但是,只要您将轴限制定义得远远超出您要可视化的数据范围,您想要实现的目标将会非常好。因为与您的评论相反,您可以像这样设置每个子图的轴限制:

# Set y ranges for each subplot
for i in range(1,3):
    for j in range(1,3):
        fig.update_yaxes(range=[-4, 4], row=i, col=j)

而不是预定义的限制,您可以从数据集中找到适当的最大值和最小值。 图表2:未缩放

enter image description here

情节 3:缩小

enter image description here

我希望这更有帮助!


1
嗨!这将是有界的垂直线,如果我滚动图形,这些线将仅从y=-2开始,并在y=2结束。目标是将它们设置为无界。 - Halogen II
此外,纵向线不应影响y轴的最小值和最大值。我可以在一个图中实现这一点,但在子图中却做不到。 - Halogen II
1
@HalogenII 最后一次编辑后,我的建议对你的效果如何? - vestland
1
谢谢@vestland,这是一个hack,但它能够完成任务。我会确保设置足够大的边界。感谢一切。 - Halogen II
希望我的英语不太糟糕,以至于我误解了问题,但是你不能通过在代码中用 yref="y domain", y0=0, y1=1 替换相应的键来获得“无限垂直线”吗? - Stefan Pinnow

1
在4.12.0版本中,新增了add_vline/add_hline方法用于绘制垂直和水平线条。其他形状也有类似的方法。请参考https://plotly.com/python/horizontal-vertical-shapes/。以下是该文档中的一个示例:
import plotly.express as px

df = px.data.iris()
fig = px.scatter(df, x="petal_length", y="petal_width")
fig.add_hline(y=0.9)
fig.add_vrect(x0=0.9, x1=2)
fig.show()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接