如何绘制字典 [英] How to plot a dictionary
问题描述
我在绘制以下值时遇到一些问题:
my_dict = {'word1':['31','131','2'],'word2':['42','33','154','21']}
我所做的是
plt.bar(my_dict.keys(), my_dict.values(), color='g')
但我收到此错误:
<块引用>TypeError:ufunc'add'不包含签名匹配的循环类型 dtype('
然后我尝试了
plt.plot(* zip(* sorted(my_dict.items())))plt.show()
但我遇到了另一个错误:
<块引用>TypeError:不可散列的类型:列表"
我会对频率感兴趣.
该如何解决?
从原始数据集中(因为我在复制代码时遇到一些错误):
my_dict = defaultdict(列表)打印({k:v for k,v in my_dict.items()})
输出:
{'word1':['122','121.2','132','132','144','144.5','144','150','150,5','150,5','150,5'],'word2':['230','230','230','230'],'word3':['542','542','540'], 'word4': ['134', '134']}
我需要绘制每个单词中值的频率(例如,对于word1,我应该将132和144的频率设为2,然后将150.5的频率设为3,将所有其他值的频率设为1).
使用 pandas
和 tdf = df.T # 转置数据帧 dfax = tdf.plot.bar()f = [df[c].value_counts().to_dict() for c in df.columns] # 值计数列表f = dict(kv for d in f for d.items()中的kv对于ax.patches中的p:如果 p.get_height() >0:#在酒吧顶部增加价值ax.annotate(format(p.get_height(),'.1f'),(p.get_x() + p.get_width()/2., p.get_height() + 10),ha ='center',va ='center',fontsize = 9,rotation = 90,xytext = (0, 10), textcoords = '偏移点')#在条形中心添加值的频率ax.annotate(format(f[p.get_height()], '.0f'),(p.get_x()+ p.get_width()/2,p.get_height()/2),ha = 'center', va = 'center', fontsize=9, rotation=0,xytext = (0, 10), textcoords = '偏移点')
tdf = df.T # 转置数据帧 dfax = tdf.plot.bar()f = [df[c].value_counts().to_dict() for c in df.columns] # 值计数列表f = dict(kv for d in f for d.items()中的kv对于ax.patches中的p:如果 p.get_height() >0:#在酒吧顶部增加价值ax.annotate(format(p.get_height(),'.1f'),(p.get_x() + p.get_width()/2., p.get_height() + 10),ha ='center',va ='center',fontsize = 9,rotation = 90,xytext = (0, 10), textcoords = '偏移点')#在条形中心添加值的频率ax.annotate(format(f[p.get_height()], '.0f'),(p.get_x()+ p.get_width()/2,p.get_height()/2),ha = 'center', va = 'center', fontsize=9, rotation=0,xytext = (0, 10), textcoords = '偏移点')
没有注释
- 通过
hue
进行着色,根据hue
,word
在此使用的列中的唯一值的数量,将条形偏离中心案件.- 在下面的示例中,所有四个单词都包含值
150.5
,因此您可以在绘图中看到它们的分组.
- 在下面的示例中,所有四个单词都包含值
- 横条是水平的以容纳大量值.
- 只需增加
figsize
高度即可.
- 只需增加
将 seaborn 导入为 snsd = {'word1': ['122', '121.2', '132', '132', '144', '144.5', '144', '150', '150.5', '150.5', '150.5''],'word2':['230','230','230','230','150.5'],'word3':['542','542','540','150.5'], 'word4': ['134', '134', '150.5']}cols = d.keys()val = list(zip_longest(* d.values()))#个数据框df = pd.DataFrame(val, columns=cols, dtype=float)#从宽转换为长df ['id'] = df.indexdfl = pd.wide_to_long(df,stubnames ='word',j ='x',i ='id').reset_index().rename(columns = {'word':'v','x':'word'}).dropna()# groupby 用于频率计数dflg = dfl.groupby('word').agg({'v': 'value_counts'}).rename(columns={'v': 'freq_count'}).reset_index().sort_values('v')# 阴谋plt.figure(figsize =(6,10))p = sns.barplot(y='v', x='freq_count', data=dflg,hue='word', orient='h')
I have some problems to plot the following values:
my_dict={'word1': ['31', '131', '2'], 'word2': ['42', '33', '154', '21']}
What I have done is
plt.bar(my_dict.keys(), my_dict.values(), color='g')
but I got this error:
TypeError: ufunc 'add' did not contain a loop with signature matching types dtype('
Then I have tried with
plt.plot(*zip(*sorted(my_dict.items())))
plt.show()
but I got this other error:
TypeError: unhashable type: 'list'
I would be interested in frequency.
What should I do to fix it?
From the original dataset (as I have got some error to replicate the code):
my_dict = defaultdict(list)
print({ k : v for k, v in my_dict.items() })
output:
{'word1': ['122', '121.2', '132', '132', '144', '144.5', '144', '150', '150,5', '150,5', '150,5'], 'word2': ['230', '230', '230', '230'], 'word3': ['542', '542', '540'], 'word4': ['134', '134']}
I would need to plot the frequency of values in each word (for example, for word1 I should have a frequency of 2 for 132 and 144, then 3 for 150.5, 1 for all the other values).
Use pandas
and zip_longest
- Pandas requires the columns to have the same length, so
zip_longest
will fill blanks withNone
. - There are a number of options to shape the data, based upon how you want it plotted.
import pandas as pd
from itertools import zip_longest
import matplotlib.pyplot as plt
# data
d = {'word1': ['122', '121.2', '132', '132', '144', '144.5', '144', '150', '150.5', '150.5', '150.5'], 'word2': ['230', '230', '230', '230'], 'word3': ['542', '542', '540'], 'word4': ['134', '134']}
# since the values lists are uneven
cols = d.keys()
val = list(zip_longest(*d.values()))
# dataframe
df = pd.DataFrame(val, columns=cols, dtype=float)
word1 word2 word3 word4
0 122.0 230.0 542.0 134.0
1 121.2 230.0 542.0 134.0
2 132.0 230.0 540.0 NaN
3 132.0 230.0 NaN NaN
4 144.0 NaN NaN NaN
5 144.5 NaN NaN NaN
6 144.0 NaN NaN NaN
7 150.0 NaN NaN NaN
8 150.5 NaN NaN NaN
9 150.5 NaN NaN NaN
10 150.5 NaN NaN NaN
plot with annotations
ax = df.plot.bar()
f = [df[c].value_counts().to_dict() for c in df.columns] # list of list of value counts
f = dict(kv for d in f for kv in d.items()) # this will break if the values for each word aren't unique
for p in ax.patches:
if p.get_height() > 0:
# add value at top of bar
ax.annotate(format(p.get_height(), '.1f'),
(p.get_x() + p.get_width() / 2., p.get_height() + 10),
ha = 'center', va = 'center', fontsize=9, rotation=90,
xytext = (0, 10), textcoords = 'offset points')
# add frequency of value at center of bar
ax.annotate(format(f[p.get_height()], '.0f'),
(p.get_x() + p.get_width() / 2., p.get_height() / 2),
ha = 'center', va = 'center', fontsize=9, rotation=0,
xytext = (0, 10), textcoords = 'offset points')
tdf = df.T # transpose dataframe df
ax = tdf.plot.bar()
f = [df[c].value_counts().to_dict() for c in df.columns] # list of list of value counts
f = dict(kv for d in f for kv in d.items()) # this will break if the values for each word aren't unique
for p in ax.patches:
if p.get_height() > 0:
# add value at top of bar
ax.annotate(format(p.get_height(), '.1f'),
(p.get_x() + p.get_width() / 2., p.get_height() + 10),
ha = 'center', va = 'center', fontsize=9, rotation=90,
xytext = (0, 10), textcoords = 'offset points')
# add frequency of value at center of bar
ax.annotate(format(f[p.get_height()], '.0f'),
(p.get_x() + p.get_width() / 2., p.get_height() / 2),
ha = 'center', va = 'center', fontsize=9, rotation=0,
xytext = (0, 10), textcoords = 'offset points')
Without annotations
- Coloring by
hue
places the bars off-center based upon the number of unique values in the column used byhue
,word
in this case.- In the example below, all four words contain the value
150.5
, so you can see them grouped in the plot.
- In the example below, all four words contain the value
- The bars are horizontal to accommodate a large number of values.
- Just increase the
figsize
height.
- Just increase the
import seaborn as sns
d = {'word1': ['122', '121.2', '132', '132', '144', '144.5', '144', '150', '150.5', '150.5', '150.5'], 'word2': ['230', '230', '230', '230', '150.5'], 'word3': ['542', '542', '540', '150.5'], 'word4': ['134', '134', '150.5']}
cols = d.keys()
val = list(zip_longest(*d.values()))
# dataframe
df = pd.DataFrame(val, columns=cols, dtype=float)
# convert from wide to long
df['id'] = df.index
dfl = pd.wide_to_long(df, stubnames='word', j='x', i='id').reset_index().rename(columns={'word': 'v', 'x': 'word'}).dropna()
# groupby for frequency counts
dflg = dfl.groupby('word').agg({'v': 'value_counts'}).rename(columns={'v': 'freq_count'}).reset_index().sort_values('v')
# plot
plt.figure(figsize=(6, 10))
p = sns.barplot(y='v', x='freq_count', data=dflg, hue='word', orient='h')
这篇关于如何绘制字典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!