Python字典多维度值的条形图绘制问题(不调整维度)
问题描述
我有一个Python字典pd_plot,键为模型标签,值是长度不一的数值数组,数组内及不同数组间存在大量重复值(比如0值)。尝试两种matplotlib条形图绘制代码均报错:
- 第一种代码报
ValueError: too many values to unpack (expected 2) - 第二种代码报
ValueError: setting an array element with a sequence
现有解决方案都要求补0统一数组维度,但因为数组本身就有大量0值,这种方法不可行,需要不调整维度的条形图绘制方法。
字典数据
pd_plot = { 'MinMaxScalerLogisticRegression': [0,0,1,6,150,200], 'StandardScalerHoeffdingTreeClassifier': [2,0,50,100], 'MaxAbsScalerKNNClassifier': [23,45,56,0,0], 'MinMaxScalerGaussianNB': [43,56,76,87,35], 'MinMaxScalerKNNClassifier': [50,2,78,135,74,0,1,5,0], 'StandardScalerKNNClassifier': [1,200], 'MinMaxScalerHoeffdingTreeClassifier': [34,35,76,87,90,98,43,32,32,4,5], 'StandardScalerLogisticRegression': [6,7,0,1,2,5], 'MaxAbsScalerHoeffdingTreeClassifier': [2] }
尝试的代码及报错
代码1及报错
import matplotlib.pylab as plt myList = pd_plot.items() myList = sorted(pd_plot) x, y = zip(*myList) plt.plot(x, y) plt.show()
报错信息:
ValueError Traceback (most recent call last) <ipython-input-23-916d14b0fed0> in <module> 2 myList = pd_plot.items() 3 myList = sorted(pd_plot) ----> 4 x, y = zip(*myList) 5 6 plt.plot(x, y) ValueError: too many values to unpack (expected 2)
代码2及报错
import matplotlib.pyplot as plt names = list(pd_plot.keys()) values = list(pd_plot.values()) plt.bar(range(len(pd_plot)), values, tick_label=names) plt.show()
报错信息:
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-24-319c3c2e7d40> in <module> 4 values = list(pd_plot.values()) 5 ----> 6 plt.bar(range(len(pd_plot)), values, tick_label=names) 7 plt.show() 7 frames /usr/local/lib/python3.7/dist-packages/matplotlib/transforms.py in from_extents(*args) 787 The *y*-axis increases upwards. 788 """ --> 789 points = np.array(args, dtype=float).reshape(2, 2) 790 return Bbox(points) 791 ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (4,) + inhomogeneous part.
错误原因分析
- 代码1错误原因:
sorted(pd_plot)仅对字典的键进行排序,返回的是纯键的列表,不是键值对元组。使用zip(*myList)解包时,每个元素是单个字符串(键),无法拆分为x和y两个部分,因此触发“too many values to unpack”错误。 - 代码2错误原因:
plt.bar()要求y轴输入为一维数值数组,但这里传入的是嵌套列表(每个元素是长度不一的数组),matplotlib无法处理这种形状不均匀的序列,因此报错。
解决方案
方案1:绘制分组条形图(保留所有元素)
针对每个标签对应的长度不一的数组,可为每个标签下的数值绘制并排小条形,通过调整x轴位置避免重叠:
import matplotlib.pyplot as plt import numpy as np # 获取排序后的键和对应值 sorted_keys = sorted(pd_plot.keys()) sorted_values = [pd_plot[key] for key in sorted_keys] # 设置条形宽度和组间距 bar_width = 0.2 group_spacing = 1.5 # 计算所有数组中的最大长度,用于设置组间偏移 max_length = max(len(vals) for vals in sorted_values) # 遍历每个标签的数值数组,绘制分组条形 for idx, (label, vals) in enumerate(zip(sorted_keys, sorted_values)): # 计算当前组每个条形的x轴位置 x_positions = np.arange(len(vals)) + idx * (max_length + group_spacing) plt.bar(x_positions, vals, width=bar_width, label=label) # 隐藏x轴刻度(因每组长度不同,统一刻度无意义) plt.xticks([]) # 放置图例到图表外侧,避免遮挡 plt.legend(bbox_to_anchor=(1.02, 1), loc='upper left') plt.tight_layout() plt.show()
方案2:绘制统计值条形图(展示数组特征)
若不需要展示数组的每个元素,可基于数组的统计指标(如均值、中位数、最大值)绘制条形图,无需统一维度:
import matplotlib.pyplot as plt import numpy as np # 计算每个数组的均值(可替换为np.median、np.max等) stats_values = [np.mean(vals) for vals in pd_plot.values()] labels = list(pd_plot.keys()) plt.bar(range(len(labels)), stats_values, tick_label=labels) # 旋转x轴标签避免重叠 plt.xticks(rotation=45, ha='right') plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者Priyanka Rajendran
相关产品推荐
相关产品推荐

