使用列表作为值从字典构建条形图

时间:2019-10-09 20:34:29

标签: arrays python-3.x dictionary matplotlib

如果这是一个菜鸟问题(我第一次尝试matpotlib),我深表歉意。 我有一本长度约为70的字典,其值是最大长度为2个元素的列表,例如:

dictionary = {
    'Product Name 1' : [10.99,20.99],
    'Product Name 2' : [50.99,10.99],
    'Product Name 3' : [40.00,15.99],
    'Product Name 4' : [50.00],
    'Product Name 5' : [50.00]
}

我尝试了以下代码:

import matplotlib.pyplot as plt
import numpy as np

c = []
v = []  

for key, val in dictionary.items():
    c.append(key)
    v.append(val)
v = np.array(v)

plt.bar(range(len(c)), v[:,0])
plt.bar(range(len(c)), v[:,1], bottom=v[:,0])
plt.xticks(range(len(c)), c)
plt.show()

当plt.bar出现索引错误时,数组索引过多。

1 个答案:

答案 0 :(得分:2)

让我们首先关注您的字典。每个键都与一个列表相关联,该列表最多可以包含两个元素。当您执行以下代码时,

dictionary = {
    'Product Name 1' : [10.99,20.99],
    'Product Name 2' : [50.99,10.99],
    'Product Name 3' : [40.00,15.99],
    'Product Name 4' : [50.00],
    'Product Name 5' : [50.00]
}
print(dictionary.values())
# dict_values([[10.99, 20.99], [50.99, 10.99], [40.0, 15.99], [50.0], [50.0]])

您可以看到输出采用子列表列表的形式,每个子列表都包含与特定键相关联的值。但是,并非所有列表都具有相同的长度。这是一个问题,因为您要将列表转换为numpy数组。实际上,您不能生成尺寸不一致的数组。结果,您将得到一个dtype object数组,该数组仅像以前一样存储子列表。

import numpy as np
print(np.array([x for x in dictionary.values()]))
print(np.array([x for x in dictionary.values()]).dtype)
# [list([10.99, 20.99]) list([50.99, 10.99]) list([40.0, 15.99])
#  list([50.0]) list([50.0])]
# object

这就是为什么在尝试切片numpy数组时会出现IndexError的原因,因为您根本无法。我在下面提出一个解决方案。使用列表推导收集键和值。将生成两个条形图,其中一个对应于原始词典列表中的每个潜在条目。对于每个条形图,使用列表推导确定条形的高度。第一个只是获取列表的第一项。第二个将获取第二个(如果存在),否则将使用0。最后,X轴上的刻度将更新以反映字典键。

import matplotlib.pyplot as plt
import numpy as np

dictionary = {
    'Product Name 1' : [10.99,20.99],
    'Product Name 2' : [50.99,10.99],
    'Product Name 3' : [40.00,15.99],
    'Product Name 4' : [50.00],
    'Product Name 5' : [50.00]
}
keys = [key for key in dictionary.keys()]
values = [value for value in dictionary.values()]
fig, ax = plt.subplots()
ax.bar(np.arange(len(keys)) - 0.2, [value[0] for value in values],
       width=0.2, color='b', align='center')
ax.bar(np.arange(len(keys)) + 0.2,
       [value[1] if len(value) == 2 else 0 for value in values],
       width=0.2, color='g', align='center')
ax.set_xticklabels(keys)
ax.set_xticks(np.arange(len(keys)))
plt.show()

enter image description here

相关问题