堆叠+分组条形图

sou*_*alo 9 python bar-chart plotly plotly-python

我正在尝试使用 python 中的plotly 创建一个条形图,它既是堆叠的又是分组的。
玩具示例(不同年份花费和赚取的钱):

import pandas as pd
import plotly.graph_objs as go

data = pd.DataFrame(
    dict(
        year=[2000,2010,2020],
        var1=[10,20,15],
        var2=[12,8,18],
        var3=[10,17,13],
        var4=[12,11,20],
    )
)

fig = go.Figure(
    data = [
        go.Bar(x=data['year'], y=data['var1'], offsetgroup=0, name='spent on fruit'),
        go.Bar(x=data['year'], y=data['var2'], offsetgroup=0, base=data['var1'], name='spent on toys'),
        go.Bar(x=data['year'], y=data['var3'], offsetgroup=1, name='earned from stocks'),
        go.Bar(x=data['year'], y=data['var4'], offsetgroup=1, base=data['var3'], name='earned from gambling'),
    ]
)
fig.show()   
Run Code Online (Sandbox Code Playgroud)

结果一开始看起来不错: 在此输入图像描述 但是看看当我关闭例如“花在水果上”时会发生什么: 在此输入图像描述 “花在玩具上”的痕迹仍然是浮动的,而不是从 0 开始。
这个问题可以修复吗?或者也许整个offsetgroup+base方法在这里不起作用。但我还能做什么呢?
谢谢!

更新:根据此 Github 问题,正在为未来的绘图版本开发堆叠、分组条形图,因此这可能不再是问题。

Saa*_*kke 12

Plotly Express(最新plotly库版本的一部分)facet_col为其条形图(以及其他图表)提供了一个参数,它允许设置附加的分组列:

此列或 array_like 中的值用于将标记分配给水平方向上的分面子图。

为了使其工作,我必须重塑示例数据:

import pandas as pd

data = pd.DataFrame(
    dict(
        year=[*[2000, 2010, 2020]*4],
        var=[*[10, 20, 15], *[12, 8, 18], *[10, 17, 13], *[12, 11, 20]],
        names=[
            *["spent on fruit"]*3,
            *["spent on toys"]*3,
            *["earned from stocks"]*3,
            *["earned from gambling"]*3,
        ],
        groups=[*["subgroup1"]*6, *["subgroup2"]*6]
    )
)
Run Code Online (Sandbox Code Playgroud)
变量 名字 团体
0 2000年 10 花在水果上 亚组1
1 2010年 20 花在水果上 亚组1
2 2020年 15 花在水果上 亚组1
3 2000年 12 花在玩具上 亚组1
4 2010年 8 花在玩具上 亚组1
5 2020年 18 花在玩具上 亚组1
6 2000年 10 从股票中赚取的 子组2
7 2010年 17 号 从股票中赚取的 子组2
8 2020年 13 从股票中赚取的 子组2
9 2000年 12 赌博赚来的 子组2
10 2010年 11 赌博赚来的 子组2
11 2020年 20 赌博赚来的 子组2

一旦采用这种格式(我相信这称为“高格式”),您可以通过一个函数调用来绘制它:

import plotly_express as px

fig = px.bar(data, x="groups", y="var", facet_col="year", color="names")
fig.show()
Run Code Online (Sandbox Code Playgroud)

Plotly Express 条形图分组和堆叠

如果您想隐藏子组标签,您可以更新 x 轴:

fig.update_xaxes(visible=False)
Run Code Online (Sandbox Code Playgroud)

Plotly Express 条形图分组和堆叠,没有 x 轴标签


Der*_*k O 8

似乎没有办法在 Plotly 中同时创建堆积条形图和分组条形图,但有一种解决方法可以解决您的问题。您需要创建子组,然后在 Plotly 中使用堆叠条形图一次绘制一个条形图,绘制var1var2与子组 1 和var3var4子组 2。

该解决方案为您提供了所需的功能,但改变了条形图的格式和美观。每个条形之间的间距相等,因为从 Plotly 的角度来看,这些是堆叠的条形(而不是分组的条形),并且我无法找到一种方法来消除 subgroup1 和 subgroup2 文本,同时又不删除年份中的年份x 轴刻度。任何 Plotly 专家请随时加入并改进我的答案!

import pandas as pd
import plotly.graph_objs as go

df = pd.DataFrame(
    dict(
        year=[2000,2010,2020],
        var1=[10,20,15],
        var2=[12,8,18],
        var3=[10,17,13],
        var4=[12,11,20],
    )
)
        
fig = go.Figure()

fig.update_layout(
    template="simple_white",
    xaxis=dict(title_text="Year"),
    yaxis=dict(title_text="Count"),
    barmode="stack",
)

groups = ['var1','var2','var3','var4']
colors = ["blue","red","green","purple"]
names = ['spent on fruit','spent on toys','earned from stocks','earned from gambling']

i = 0
for r, n, c in zip(groups, names, colors):
    ## put var1 and var2 together on the first subgrouped bar
    if i <= 1:
        fig.add_trace(
            go.Bar(x=[df.year, ['subgroup1']*len(df.year)], y=df[r], name=n, marker_color=c),
        )
    ## put var3 and var4 together on the first subgrouped bar
    else:
        fig.add_trace(
            go.Bar(x=[df.year, ['subgroup2']*len(df.year)], y=df[r], name=n, marker_color=c),
        )
    i+=1

fig.show()   
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 谢谢,这真是太聪明了!这也相当麻烦,也许这需要向plotly 团队提出功能请求。 (2认同)