Python Plotly 子图中的条形标记宽度

1 投票
1 回答
54 浏览
提问于 2025-04-13 20:52

我希望我子图中柱子的标记线能够自动调整,正好与每个柱子的宽度一致。目前,它们的宽度只占了一部分:

子图示例

这是我的代码:

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

subplots = ['A','B','C','D']
fig = make_subplots(rows=2, cols=2, subplot_titles=subplots)
layout = go.Layout(
    barmode='stack',
    height=1000,
    width=1000,
    bargap=0.2,
)
fig.update_layout(layout)

directions = ['north','east','south','west']
levels = ['top','middle','bottom']

row = 1
col = 1
for subplot in subplots:
    for direction in directions:
        fig.add_trace(
            go.Bar(
                x=levels,
                y=np.random.randint(20, size=3),
            ),
            row=row,
            col=col,
        ) ,
    fig.add_trace(
        go.Scatter(
            mode='markers',
            x=levels,
            y=np.random.randint(20, size=3) + 2,
            marker={
                'symbol':   'line-ew-open',
                'size':     24,
                'color':    'black',
            }
        ),
        row=row,
        col=col,
    )
    ## move on
    if col == 2:
        row += 1
        col = 1
    else:
        col += 1

fig.show()

根据r-beginners这里的回答,似乎可以通过使用fig.full_figure_for_development()来实现这个功能,这样在缩放时也能自动调整。但我不太明白怎么提取这个。

任何帮助都很感激!

1 个回答

0

使用 fig.add_shape(type="line") 这个方法,你可以在图表中插入可缩放的线条。通过对你原来的代码做一些修改,你就能在所有子图的每个柱子上添加线条。

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

column_width = .6
subplots = ['A','B','C','D']
directions = ['north','east','south','west']
levels = ['top','middle','bottom']

fig = make_subplots(rows=2, cols=2, subplot_titles=subplots)
layout = go.Layout(
    barmode='stack',
    height=1000,
    width=1000,
    bargap=1-column_width,
)
fig.update_layout(layout)

row = 1
col = 1
for number, subplot in enumerate(subplots):
    for direction in directions:
        fig.add_trace(
            go.Bar(
                x=levels,
                y=np.random.randint(20, size=3),
            ),
            row=row,
            col=col,
        )
    # add marker lines
    bars_y = [bar.y for bar in fig.data[number*4:number*4+4]]
    for pos,level in enumerate(levels):
        y_pos = sum([a[pos] for a in bars_y])/4
        fig.add_shape(type="line",
                      x0=pos-column_width/2,
                      x1=pos+column_width/2,
                      y0=y_pos,
                      y1=y_pos,
                      row=row,
                      col=col)
    ## move on
    if col == 2:
        row += 1
        col = 1
    else:
        col += 1

fig.show(renderer="browser")

最终的效果大概是这样的。

带线的柱状图

我检查过的其他方法有几个。第一个是 fig.add_hline,但这个方法会产生无限长度的线条,这并不是你想要的。第二个是添加标记,但它没有长度的参数。最后,在深入研究 fig.full_figure_for_development() 后,你可以在布局的 xaxis 部分找到 xrange,但这个范围和你设置的范围是一样的。

撰写回答