Plotly:如何对条形图上显示的“文本”值求和?

Posted

技术标签:

【中文标题】Plotly:如何对条形图上显示的“文本”值求和?【英文标题】:Plotly: how to sum the "text" values displayed on a bar chart? 【发布时间】:2020-09-28 20:33:00 【问题描述】:

我正在Plotly Express 中创建一个条形图,并想对图中显示的“文本”值求和。

我的数据如下:

import plotly.express as px
import pandas as pd
df = pd.DataFrame('Make':['Mercedes', 'BMW', 'Mercedes', 'Mercedes', 'Chrysler', 'Chrysler', 'Chrysler', 'Chrysler', 'BMW', 'Chrysler', 'BMW', 'Mercedes', 'BMW', 'Mercedes'],
                          'Dimension':['Styling', 'Styling', 'Price', 'Styling', 'MPG', 'MPG', 'Styling', 'Styling', 'MPG', 'MPG', 'Price', 'Price', 'Styling', 'MPG'],
                          'Country':['USA', 'USA', 'USA', 'Germany', 'USA', 'USA', 'USA', 'England', 'Germany', 'USA', 'Germany', 'Poland', 'Italy', 'USA'],
                          'LowValue':['64', '61', '70', '65', '59', '68', '63', '57', '58', '55', '69', '63', '69', '61'],
                          'HighValue':['82', '95', '93', '95', '87', '93', '85', '85', '95', '92', '83', '87', '80', '80'])

我使用以下方法在Plotly Express 中绘制这些数据:

px.bar(df, x='Make', y='LowValue', color='Dimension', 
       barmode='group', text='LowValue')

如您所见,Mercedes 的 Styling 条显示两个值:65 和 64(因为它们是基础数据点)。

问题:有没有办法将基础数据合并为单个值并仅显示该单个总和值?

例如,在梅赛德斯的Styling 栏顶部显示 129(基础数据点的总和)(而不是显示 65 和 64)。

谢谢!

【问题讨论】:

只是为了澄清你想在顶部显示 64、65 和 129 吗? 不,我不想显示 64 和 65。我想在条形顶部显示总和值。 在我看来,没有一种简单的方法可以做到这一点,您应该为每个“偏移组”使用注释和偏移量 【参考方案1】:

在创建条形图之前,您可以使用 pandas groupby() 通过 MakeDimension 计算 LowValue 的总数:

import plotly.express as px
import pandas as pd

df = pd.DataFrame('Make': ['Mercedes', 'BMW', 'Mercedes', 'Mercedes', 'Chrysler', 'Chrysler', 'Chrysler', 'Chrysler', 'BMW', 'Chrysler', 'BMW', 'Mercedes', 'BMW', 'Mercedes'],
                   'Dimension': ['Styling', 'Styling', 'Price', 'Styling', 'MPG', 'MPG', 'Styling', 'Styling', 'MPG', 'MPG', 'Price', 'Price', 'Styling', 'MPG'],
                   'Country': ['USA', 'USA', 'USA', 'Germany', 'USA', 'USA', 'USA', 'England', 'Germany', 'USA', 'Germany', 'Poland', 'Italy', 'USA'],
                   'LowValue': ['64', '61', '70', '65', '59', '68', '63', '57', '58', '55', '69', '63', '69', '61'],
                   'HighValue': ['82', '95', '93', '95', '87', '93', '85', '85', '95', '92', '83', '87', '80', '80'])

df['LowValue'] = df['LowValue'].astype(int)

df1 = pd.DataFrame(df.groupby(by=['Make', 'Dimension'])['LowValue'].sum())

df1.reset_index(inplace=True)

fig = px.bar(df1, x='Make', y='LowValue', color='Dimension', barmode='group', text='LowValue')

fig.show()

【讨论】:

但是这样你就错过了堆叠的条形图。 @rpanai - 不需要堆叠条。事实上,底层数据包含每个条形图的数百个数据点,绘制时会造成混乱。 谢谢你,@gflavia。使用 groupby() 效果非常好。 @equanimity 在这种情况下,您应该编辑您的问题。从实际问题来看,您希望更改注释以保持您使用的绘图格式。【参考方案2】:

我想有办法只要你愿意修改你原来的df

数据样本

import plotly.express as px
import numpy as np
import pandas as pd

df = pd.DataFrame('Make':['Mercedes', 'BMW', 'Mercedes', 'Mercedes', 'Chrysler', 'Chrysler', 'Chrysler', 'Chrysler', 'BMW', 'Chrysler', 'BMW', 'Mercedes', 'BMW', 'Mercedes'],
                          'Dimension':['Styling', 'Styling', 'Price', 'Styling', 'MPG', 'MPG', 'Styling', 'Styling', 'MPG', 'MPG', 'Price', 'Price', 'Styling', 'MPG'],
                          'Country':['USA', 'USA', 'USA', 'Germany', 'USA', 'USA', 'USA', 'England', 'Germany', 'USA', 'Germany', 'Poland', 'Italy', 'USA'],
                          'LowValue':['64', '61', '70', '65', '59', '68', '63', '57', '58', '55', '69', '63', '69', '61'],
                          'HighValue':['82', '95', '93', '95', '87', '93', '85', '85', '95', '92', '83', '87', '80', '80'])

# we better use int here
df[["LowValue", "HighValue"]] = df[["LowValue", "HighValue"]].astype(int)

排列数据

现在你想得到 LowValue 的总和,但因为你只想显示一个你需要玩一点

df["LowValueSum"] = df.groupby(["Make", "Dimension"])["LowValue"]\
                      .transform(sum)

# Here we consider the latest index within the goupby only 
df["idx_max"] = df.groupby(["Make", "Dimension"])["LowValueSum"]\
                  .transform(lambda x: x.index.max())

df.loc[df["idx_max"] != df.index, "LowValueSum"] = np.nan

# now you can eventually drop the previous colums
# df = df.drop("idx_max", axis=1)

情节

fig = px.bar(df, 
             x='Make', 
             y='LowValue',
             color='Dimension', 
             barmode='group',
             text='LowValueSum',
             hover_data="Country":True,
                         "Dimension":False,
                         "Make":False,
             hover_name="Dimension")
fig.update_traces(textposition="outside")

更新鉴于182 看起来非常接近上限,您最终可以添加这一行

fig.update_yaxes(range=[0, df["LowValueSum"].max() * 1.2])

【讨论】:

以上是关于Plotly:如何对条形图上显示的“文本”值求和?的主要内容,如果未能解决你的问题,请参考以下文章

Plotly 条形图上的错误栏阻止的文本

在条形图上的 Plotly 中更改轴/图例名称

如何更改使用 Plotly Express 创建的堆积条形图的文本方向?

Plotly Express 防止文本值出现在悬停模板中

Plotly:如何在甘特图上标记条形?

在这种情况下,如何使用 barh() 在条形图上显示值? [复制]