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)
如果您想隐藏子组标签,您可以更新 x 轴:
fig.update_xaxes(visible=False)
Run Code Online (Sandbox Code Playgroud)
似乎没有办法在 Plotly 中同时创建堆积条形图和分组条形图,但有一种解决方法可以解决您的问题。您需要创建子组,然后在 Plotly 中使用堆叠条形图一次绘制一个条形图,绘制var1和var2与子组 1 和var3与var4子组 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)