ggplot(plotnine)分组柱状图缺失观测时的position_dodge2定位问题
解决分组柱状图无数据组留空白的问题
要让无观测数据的组保留空白位置,不让剩余柱子居中,需要两步核心操作:补全缺失的分组数据,再调整柱状图的位置参数。
关键修改点
- 补全数据:确保每个
homeworld都包含male和female两个性别组,无数据的组计数设为0 - 调整位置参数:移除
position_dodge2的preserve="single"参数,改用常规的position_dodge固定柱子位置
修改后的完整代码
import plotnine as pn import pandas as pd import plotnine.colors as pf # 补充原代码用到的颜色模块 data = pd.read_csv("starwars.csv") # 数据来源:https://github.com/tidyverse/dplyr/blob/main/data-raw/starwars.csv hw = data["homeworld"].value_counts().head(6) data = data.merge(hw, left_on="homeworld", right_on="homeworld") # 预处理:补全所有性别-家园组合,无数据的填0 data = data.dropna(subset=["gender"]) count_data = ( data.groupby(["homeworld", "gender"]) .size() .unstack(fill_value=0) .reset_index() .melt(id_vars="homeworld", var_name="gender", value_name="count") ) # 按男性数量排序家园顺序 order = ( count_data[count_data["gender"] == "male"] .sort_values("count", ascending=False)["homeworld"] .tolist() ) ( pn.ggplot(count_data, pn.aes(x="factor(homeworld)", y="count", fill="factor(gender, ['male', 'female'])")) + pn.geom_bar(stat="identity", position=pn.position_dodge(width=0.8)) # 固定分组柱子位置 + pn.scale_fill_manual({"male": pf.color.BLUE, "female": pf.color.RED}) + pn.scale_x_discrete(limits=order) + pn.scale_y_continuous(expand=(0, 0)) + pn.labs( title="Difference between males and females", y="Count", x="Homeworld", fill='Gender', caption="There is a significant difference between the number of males and females on Naboo and Tatooine.", ) )
代码说明
- 通过
groupby+unstack+melt的组合操作,生成每个家园对应两种性别的完整计数,无数据的组自动填充0,确保每个x轴类别下都有两组数据 - 改用
stat="identity"直接使用统计好的计数,搭配position_dodge(width=0.8)让柱子按分组固定位置排列,即使某组计数为0,也会保留对应的空白位置 - 调整排序逻辑,基于男性计数确定x轴家园顺序,符合需求
内容的提问来源于stack exchange,提问作者Petr Hála
相关产品推荐
相关产品推荐

