You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何去除Plotly Python分面分组条形图中未使用类别的间隙

解决Plotly分面分组条形图移除跨分面预留间隙的问题

Plotly Express的分面功能会默认将所有子图的类别(这里是action)做全局统一,哪怕某个分面对应的动物根本没有该类别,也会预留空白位置,导致条形之间出现不必要的间隙。要实现仅保留子图内分组间隙、移除跨分面专属类别预留空间的效果,直接用Plotly Graph Objects手动构建子图是最可靠的方法,因为可以为每个子图单独指定可用的类别集合。

具体实现方案

  1. 按分面变量animal拆分数据集,每个动物单独处理
  2. 创建垂直排列的子图(对应原代码的facet_row布局)
  3. 为每个子图添加对应动物的分组条形,仅使用该动物实际存在的action类别
  4. 统一调整颜色、轴标签、布局等,保证视觉一致性

完整代码示例

import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots

data = [
    [1, 10, "dog", "run"], 
    [2, 15, "dog", "run"],
    [2, 13, "fish", "dive"],
    [1, 14, "fish", "swim"],
    [2, 13, "dog", "bark"],
    [1, 12, "dog", "growl"],
    [2, 12, "dog", "growl"],
    [1, 16, "fish", "dive"],
    [2, 7, "fish", "blub"],
    [1, 7, "fish", "swim"]
]
df = pd.DataFrame(data, columns=['day', 'temperature', "animal", "action"])

# 按animal拆分数据
animal_groups = df.groupby('animal')
animals = list(animal_groups.groups.keys())

# 创建垂直子图,共享x轴减少冗余
fig = make_subplots(
    rows=len(animals), cols=1,
    subplot_titles=animals,
    shared_xaxes=True,
    vertical_spacing=0.1
)

# 预定义action颜色映射,保证同一action在不同子图颜色一致
action_colors = {
    "run": "#636EFA", "bark": "#EF553B", "growl": "#00CC96",
    "dive": "#AB63FA", "swim": "#FFA15A", "blub": "#19D3F3"
}

# 逐个填充子图
for row_idx, (animal, group_df) in enumerate(animal_groups, 1):
    # 获取当前动物的所有action和day值
    unique_actions = group_df['action'].unique()
    sorted_days = sorted(group_df['day'].unique().astype(str))
    
    # 为每个action添加条形
    for action in unique_actions:
        action_data = group_df[group_df['action'] == action]
        # 整理每个day对应的温度值(和原代码逻辑一致)
        day_temp_map = {str(d): action_data[action_data['day'] == int(d)]['temperature'].values[0] for d in sorted_days}
        
        fig.add_trace(
            go.Bar(
                y=sorted_days,
                x=[day_temp_map[d] for d in sorted_days],
                name=action,
                orientation='h',
                marker_color=action_colors[action]
            ),
            row=row_idx, col=1
        )
    
    # 设置子图y轴标签
    fig.update_yaxes(title_text="Day", row=row_idx, col=1)

# 全局布局调整
fig.update_layout(
    barmode='group',  # 保留子图内分组条形的间隙
    height=600,
    title_text="Temperature by Animal, Day and Action",
    legend_title_text="Action"
)

fig.show()

效果说明

通过这种方式,每个子图只会加载对应动物实际存在的action类别,不会为其他动物的专属action预留空白空间;同时barmode='group'会保留子图内分组条形之间的间隙,完全满足你的需求。

内容的提问来源于stack exchange,提问作者crazysantaclaus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 09:14:57