首页 > 解决方案 > 在 Python 中绘制一个双条形图,其值来自两个不同的字典

问题描述

我有两个字母字典,其值为字符的频率。当我尝试使用下面的代码绘制它们时,出现以下错误:

ValueError: shape mismatch: objects cannot be broadcast to a single shape

import string
import matplotlib.pyplot as plt

labels = list(string.ascii_uppercase)

N = len(labels)

dict_1 = {'A': 0.08167, 'B': 0.01492, 'C': 0.02782, 'D': 0.04253, 'E': 0.12702, 'F': 0.02228, 'G': 0.02015, 'H': 0.06094, 'I': 0.06966, 'J': 0.00153, 'K': 0.00772, 'L': 0.04025, 'M': 0.02406, 'N': 0.06749, 'O': 0.07507, 'P': 0.01929, 'Q': 0.00095, 'R': 0.05987, 'S': 0.06327, 'T': 0.09056, 'U': 0.02758, 'V': 0.00978, 'W': 0.0236, 'X': 0.0015, 'Y': 0.01974, 'Z': 0.00074}
dict_2 = {'P': 0.05776173285198556, 'U': 0.05776173285198556, 'A': 0.09025270758122744, 'O': 0.05415162454873646, 'L': 0.1263537906137184, 'M': 0.02888086642599278, 'V': 0.06859205776173286, 'S': 0.061371841155234655, 'D': 0.02888086642599278, 'N': 0.032490974729241874, 'J': 0.04332129963898917, 'I': 0.021660649819494584, 'F': 0.036101083032490974, 'B': 0.032490974729241874, 'H': 0.08664259927797834, 'C': 0.007220216606498195, 'W': 0.032490974729241874, 'Y': 0.05415162454873646, 'X': 0.007220216606498195, 'Z': 0.05054151624548736, 'R': 0.007220216606498195, 'E': 0.0036101083032490976, 'K': 0.0036101083032490976, 'T': 0.007220216606498195}

X = np.arange(len(dict_1))
bar_width = 0.45

fig = plt.figure( figsize=(17,5) )

ax = plt.subplot(111)
ax.bar(X, dict_1.values(), bar_width, color='blue', align='center', hatch='//')
ax.bar(X-bar_width, dict_2.values(), bar_width, color='green', align='center', hatch='//')
ax.legend(('Usual English','Your Text'), fontsize = 15)

plt.xticks(X-(bar_width/2), dict_1.keys())
plt.xlabel('Character', fontsize = 15)
plt.ylabel('Frequency', fontsize = 15)
plt.title("Frequency Analysis", fontsize=17)
plt.show()

我使用与第一个字典相同的字典构建代码,并认为如果我使用不同的字母字典,它会起作用。当我使用相同的字典时,我得到以下图:在此处输入图像描述

我希望绘图为每个字符显示两个具有不同值(对应于它来自的字典中的值)的条形图。

标签: pythonmatplotlib

解决方案


您需要根据合并的键以某种方式从每个字典中获取值。像这样:

>>> d1 = {'A': 10, 'C': 20, 'B': 42}
>>> d2 = {'X': 13, 'B': 21}
>>>
>>> d1.keys()
dict_keys(['A', 'C', 'B'])
>>> d2.keys()
dict_keys(['X', 'B'])
>>> all_keys = sorted(d1.keys() | d2.keys())
>>> all_keys
['A', 'B', 'C', 'X']
>>>
>>> d1_values = [d1.get(k, 0) for k in all_keys]
>>> d1_values
[10, 42, 20, 0]
>>>
>>> d2_values = [d2.get(k, 0) for k in all_keys]
>>> d2_values
[0, 21, 0, 13]

all_keysd1_values绘制图d2_values

import matplotlib.pyplot as plt
import numpy as np

dict_1 = {'A': 0.08167, 'B': 0.01492, 'C': 0.02782, 'D': 0.04253, 'E': 0.12702, 'F': 0.02228, 'G': 0.02015, 'H': 0.06094, 'I': 0.06966, 'J': 0.00153, 'K': 0.00772, 'L': 0.04025, 'M': 0.02406, 'N': 0.06749, 'O': 0.07507, 'P': 0.01929, 'Q': 0.00095, 'R': 0.05987, 'S': 0.06327, 'T': 0.09056, 'U': 0.02758, 'V': 0.00978, 'W': 0.0236, 'X': 0.0015, 'Y': 0.01974, 'Z': 0.00074}
dict_2 = {'P': 0.05776173285198556, 'U': 0.05776173285198556, 'A': 0.09025270758122744, 'O': 0.05415162454873646, 'L': 0.1263537906137184, 'M': 0.02888086642599278, 'V': 0.06859205776173286, 'S': 0.061371841155234655, 'D': 0.02888086642599278, 'N': 0.032490974729241874, 'J': 0.04332129963898917, 'I': 0.021660649819494584, 'F': 0.036101083032490974, 'B': 0.032490974729241874, 'H': 0.08664259927797834, 'C': 0.007220216606498195, 'W': 0.032490974729241874, 'Y': 0.05415162454873646, 'X': 0.007220216606498195, 'Z': 0.05054151624548736, 'R': 0.007220216606498195, 'E': 0.0036101083032490976, 'K': 0.0036101083032490976, 'T': 0.007220216606498195}

all_keys = sorted(dict_1.keys() | dict_2.keys())
d1_values = [dict_1.get(k, 0) for k in all_keys]
d2_values = [dict_2.get(k, 0) for k in all_keys]

X = np.arange(len(all_keys))
bar_width = 0.45

fig = plt.figure( figsize=(17,5) )

ax = plt.subplot(111)
ax.bar(X, d1_values, bar_width, color='blue', align='center', hatch='//')
ax.bar(X-bar_width, d2_values, bar_width, color='green', align='center', hatch='//')
ax.legend(('Usual English','Your Text'), fontsize = 15)

plt.xticks(X-(bar_width/2), all_keys)
plt.xlabel('Character', fontsize = 15)
plt.ylabel('Frequency', fontsize = 15)
plt.title("Frequency Analysis", fontsize=17)
plt.show()

推荐阅读