Plotly Stacked Bar Chart 文本注释问题

Plotly Stacked Bar Chart text annotation issue

所以,我有这个简化的数据框,我正在使用 plotly.graph_objects 绘制带有文本注释的堆叠条形图。 我从 Salary 列中得到了我想要的文本,但我无法从值明显较低的 Age 列中得到相同的文本。我希望这些注释大小相同并位于每个栏的顶部。 我怎样才能使文本注释对年龄列也可见?

请在下面找到我的代码:

data = {'Name':['Tom', 'Nick', 'Jack'],
        'Age':[18, 21, 19],
        'Salary':[500, 700, 900]}
df_new=pd.DataFrame(data)

fig = go.Figure(go.Bar(x = df_new["Name"],
                       y = df_new["Age"],name='Age',text=df_new["Age"],
                       textposition='outside'))
fig.add_bar(x = df_new["Name"],
            y = df_new["Salary"],name='Salary',text=df_new["Salary"],
            textposition='outside')
fig.update_layout(barmode='stack',
                  title = 'Age - Salary',
                  xaxis_title="Name",
                  yaxis_title="Age / Salary")

提前致谢!

我认为您必须从 2 种可能的解决方案中进行选择。首先,通过使用 barmode = stack 参数,您进行堆叠,从而对 age 和 salary 的值求和。条形图的高度将为 age + salary,这样汤姆的条形图高度将为 500 + 18 = 518。我不建议这样做,因为在我看来高度应该反映标注值。


解决方案 1 - 分组条形图

此解决方案基于将条形码更改为 barmode = group。这将形成两个独立的条形图,它们有自己的标注和高度来反映它们的值。 我还添加了 width 参数来制作更漂亮的纵横比。

fig = go.Figure()
fig.add_bar(x = df_new["Name"],
            y = df_new["Age"],name='Age',text=df_new["Age"],
            width = [0.3]*len(df_new),
            )

fig.add_bar(x = df_new["Name"],
            y = df_new["Salary"],name='Salary',text=df_new["Salary"],
            width = [0.3]*len(df_new)
            )
fig.update_layout(barmode='group',
                  title = 'Age - Salary',
                  xaxis_title="Name",
                  yaxis_title="Age / Salary"
                  )
fig.update_traces(
    textposition='outside'
)
fig.update_yaxes(range=[0,1000])

解决方案 2 - 添加辅助 y 轴

我更喜欢这个解决方案,因为两个类别的相对大小都可以缩放到它们自己的域;这使得图表更具可读性。这使用 make_subplots 创建两个轴和 secondary_y 参数。我通过调整轴的宽度和范围使两个条都可见。

根据数据,您必须根据自己的喜好手动重新缩放。您还可以将 opacity 用于透视条,但您仍然有重叠数据标注的风险。

from plotly.subplots import make_subplots

fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_bar(
    x=df_new["Name"],
    y=df_new["Age"],
    name="Age",
    text=df_new["Age"],
    width=[0.3] * len(df_new),
    secondary_y=True,
    textposition="outside"
)
fig.add_bar(
    x=df_new["Name"],
    y=df_new["Salary"],
    name="Salary",
    text=df_new["Salary"],
    width=[0.5] * len(df_new),
    secondary_y=False,
    textposition="outside"
)

fig.update_yaxes(range=[0, 1000], title='Salary', secondary_y=False)
fig.update_yaxes(range=[0, 45], title='Age', secondary_y=True)
fig.update_layout(title="Age and Salary", xaxis_title="Name")