按年份为unit_id上色的楼层RFS堆叠条形图可扩展实现咨询
可扩展的水平堆叠条形图实现方案
核心优化逻辑是避免手动拆分不同order层级的数据,通过自动计算堆叠偏移量适配任意数量的单元/order层级,同时保留年份映射颜色的逻辑,以下是两种常用的可扩展实现:
方案1:原生Matplotlib循环实现(无额外依赖,适配任意order数量)
不需要手动拆分order层级,无论每个楼层有多少个单元、order有多少级都可以自动适配:
import pandas as pd import matplotlib.pyplot as plt from matplotlib.patches import Patch # 测试数据和颜色映射和原逻辑保持一致 df_build = pd.DataFrame({ 'floor':[1,1,1,2,2,2,3,3,3], 'unidad':[100,101,102,200,201,202,300,301,302], 'rsf':[2000,1000,1500,1500,2000,1000,1000,1500,2000], 'order':[0,1,2,0,1,2,0,1,2], 'year':[2008,2009,2010,2009,2010,2011,2010,2011,2012] }) assign_colors = {2008:'tab:red',2009:'tab:blue',2010:'tab:green',2011:'tab:pink',2012:'tab:olive'} # 预先按楼层、order排序,避免数据顺序错误 df_build = df_build.sort_values(['floor', 'order']).reset_index(drop=True) # 自动计算每个单元的堆叠左偏移:同楼层前序单元的rsf总和 df_build['left_offset'] = df_build.groupby('floor')['rsf'].cumsum().shift(fill_value=0) # 映射年份对应的颜色 df_build['color'] = df_build['year'].map(assign_colors) width = 0.35 fig, ax = plt.subplots() # 循环所有单元绘制,不需要拆分order层级 for _, row in df_build.iterrows(): ax.barh(row['floor'], row['rsf'], width, left=row['left_offset'], color=row['color']) ax.set_ylabel('floor') ax.set_title('Stacking Plan') # 可选:添加年份图例 legend_elements = [Patch(facecolor=color, label=str(year)) for year, color in assign_colors.items()] ax.legend(handles=legend_elements, bbox_to_anchor=(1.05, 1), loc='upper left') plt.tight_layout() plt.show()
方案2:Pandas内置plot实现(代码更简洁)
如果追求代码简洁,可以用透视表+pandas内置绘图能力实现,代码量更小:
import pandas as pd import matplotlib.pyplot as plt from matplotlib.patches import Patch df_build = pd.DataFrame({ 'floor':[1,1,1,2,2,2,3,3,3], 'unidad':[100,101,102,200,201,202,300,301,302], 'rsf':[2000,1000,1500,1500,2000,1000,1000,1500,2000], 'order':[0,1,2,0,1,2,0,1,2], 'year':[2008,2009,2010,2009,2010,2011,2010,2011,2012] }) assign_colors = {2008:'tab:red',2009:'tab:blue',2010:'tab:green',2011:'tab:pink',2012:'tab:olive'} df_build['color'] = df_build['year'].map(assign_colors) # 透视表处理:行是floor,列是order,值分别对应rsf和颜色 df_pivot = df_build.pivot(index='floor', columns='order', values='rsf') color_pivot = df_build.pivot(index='floor', columns='order', values='color') # 直接绘制水平堆叠条形图 ax = df_pivot.plot.barh(stacked=True, color=color_pivot.values, width=0.35, figsize=(8, 5)) ax.set_title('Stacking Plan') ax.set_ylabel('floor') # 添加年份图例 legend_elements = [Patch(facecolor=color, label=str(year)) for year, color in assign_colors.items()] ax.legend(handles=legend_elements, bbox_to_anchor=(1.05, 1), loc='upper left') plt.tight_layout() plt.show()
两种方案都不需要手动处理order层级,新增楼层、单元、order值都不需要修改核心逻辑,适配任意规模的数据集。
内容的提问来源于stack exchange,提问作者Alamond13
相关产品推荐
相关产品推荐

