3D堆叠柱状图调用plt.legend()出现AttributeError错误原因解析
解决Matplotlib 3D堆叠柱状图图例报错AttributeError的问题
错误原因
ax.bar3d()一次性绘制多个柱子时,返回的是多个PolyCollection对象组成的元组,而非单个Artist对象。调用legend()时,Matplotlib的图例处理器错误地将这个元组当作单个PolyCollection处理,尝试访问colors.size属性——但元组没有size属性,因此抛出AttributeError。此外,默认图例逻辑本身不支持直接识别3D柱状图的批量绘制结果,即便无报错,图例也无法正常显示。
解决方案
方法1:手动创建图例条目
通过matplotlib.patches.Patch手动构建图例元素,指定对应柱状图的颜色和标签:
%matplotlib import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Patch x = y = np.array([1, 2]) fig = plt.figure(figsize=(5, 3)) ax1 = fig.add_subplot(111, projection='3d') # 绘制两组柱状图,保存返回的集合对象 bars_group1 = ax1.bar3d(x, y, [0,0], 0.5, 0.5, [1,1], shade=True) bars_group2 = ax1.bar3d(x, y, [1,1], 0.5, 0.5, [1,1], shade=True) # 从每组中取第一个柱子的颜色创建图例元素 legend_handles = [ Patch(facecolor=bars_group1[0].get_facecolor(), label='a'), Patch(facecolor=bars_group2[0].get_facecolor(), label='b') ] ax1.legend(handles=legend_handles) plt.show()
方法2:逐个绘制并收集单个Artist
如果需要更精细的控制,可以逐个绘制柱子,收集单个PolyCollection对象作为图例的handle:
%matplotlib import numpy as np import matplotlib.pyplot as plt x = y = np.array([1, 2]) fig = plt.figure(figsize=(5, 3)) ax1 = fig.add_subplot(111, projection='3d') legend_handles = [] # 绘制第一组柱子,收集单个artist for xi, yi, z_base in zip(x, y, [0, 0]): bar = ax1.bar3d(xi, yi, z_base, 0.5, 0.5, 1, shade=True)[0] legend_handles.append(bar) # 绘制第二组柱子,收集单个artist for xi, yi, z_base in zip(x, y, [1, 1]): bar = ax1.bar3d(xi, yi, z_base, 0.5, 0.5, 1, shade=True)[0] legend_handles.append(bar) # 传入handle和标签创建图例 ax1.legend(handles=legend_handles, labels=['a', 'b']) plt.show()
两种方法都能绕过bar3d返回元组导致的图例处理错误,让图例正常显示。
内容的提问来源于stack exchange,提问作者gboffi
相关产品推荐
相关产品推荐

