如何用循环基于DataFrame创建Matplotlib堆叠柱状图?
解决Matplotlib堆叠柱状图循环实现的问题
你手动编写的堆叠柱状图代码能生成正确结果,但冗余度高;尝试用循环简化时,堆叠部分缺失,核心问题是循环中没有正确累加前序所有柱子的高度作为当前柱子的bottom值。
原正确代码
# Setting up all our subplots fig, ax = plt.subplots() # Editing each bars ax.bar(df21.index, df21["mac_share"], label= "mac_share") ax.bar(df21.index, df21["service_share"], label = "service_share", bottom = df21["mac_share"]) ax.bar(df21.index, df21["accessories_share"], label = "accessories_share", bottom = df21["service_share"] + df21["mac_share"]) ax.bar(df21.index, df21["ipad_share"], label = "ipad_share", bottom = df21["service_share"] + df21["mac_share"] + df21["accessories_share"]) ax.bar(df21.index, df21["iphone_share"], label = "iphone_share", bottom = df21["service_share"] + df21["mac_share"] + df21["accessories_share"] + df21["ipad_share"]) # Adding graphs element ax.set_xticklabels(df21.index, rotation=45) ax.set_ylabel("Sales shares in %") ax.legend() # Showing graphs plt.show()
错误循环代码的问题
你的循环代码里,bottom =+ df21[shares[i]]是错误写法(等价于bottom = df21[shares[i]]),而且每次只取了前一个列的值,没有累加所有之前的列,导致后续柱子的bottom值错误,无法正确堆叠。
# Setting up all our subplots fig, ax = plt.subplots() # Recalling our names of columns shares = ['mac_share', 'service_share', 'accessories_share', 'ipad_share', 'iphone_share'] # Editing the first bar ax.bar(df21.index, df21[shares[0]], label= shares[0]) # Looping through our shares list for i in range(len(shares)-1): ax.bar(df21.index, df21[shares[i+1]], label = shares[i+1], bottom =+ df21[shares[i]]) # Adding graphs details ax.set_xticklabels(df21.index, rotation=45) ax.set_ylabel("Sales shares in %") ax.legend() # plotting my graph plt.show()
正确的循环实现方式
方式1:维护累加的bottom变量
fig, ax = plt.subplots() shares = ['mac_share', 'service_share', 'accessories_share', 'ipad_share', 'iphone_share'] # 初始化bottom为0,逐步累加 bottom = 0 for share in shares: ax.bar(df21.index, df21[share], label=share, bottom=bottom) bottom += df21[share] ax.set_xticklabels(df21.index, rotation=45) ax.set_ylabel("Sales shares in %") ax.legend() plt.show()
方式2:利用DataFrame的累加求和(更简洁)
fig, ax = plt.subplots() shares = ['mac_share', 'service_share', 'accessories_share', 'ipad_share', 'iphone_share'] # 遍历列,用前序列的和作为bottom for i, share in enumerate(shares): if i == 0: ax.bar(df21.index, df21[share], label=share) else: # 计算当前列之前所有列的累加和 bottom = df21[shares[:i]].sum(axis=1) ax.bar(df21.index, df21[share], label=share, bottom=bottom) ax.set_xticklabels(df21.index, rotation=45) ax.set_ylabel("Sales shares in %") ax.legend() plt.show()
两种方式都能实现和手动代码完全一致的堆叠效果,同时大幅减少冗余代码。
内容的提问来源于stack exchange,提问作者Thefinsloth
相关产品推荐
相关产品推荐

