如何去除Plotly Python分面分组条形图中未使用类别的间隙
解决Plotly分面分组条形图移除跨分面预留间隙的问题
Plotly Express的分面功能会默认将所有子图的类别(这里是action)做全局统一,哪怕某个分面对应的动物根本没有该类别,也会预留空白位置,导致条形之间出现不必要的间隙。要实现仅保留子图内分组间隙、移除跨分面专属类别预留空间的效果,直接用Plotly Graph Objects手动构建子图是最可靠的方法,因为可以为每个子图单独指定可用的类别集合。
具体实现方案
- 按分面变量
animal拆分数据集,每个动物单独处理 - 创建垂直排列的子图(对应原代码的
facet_row布局) - 为每个子图添加对应动物的分组条形,仅使用该动物实际存在的
action类别 - 统一调整颜色、轴标签、布局等,保证视觉一致性
完整代码示例
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
相关产品推荐
相关产品推荐

