如何绘制字典 [英] How to plot a dictionary

查看:60
本文介绍了如何绘制字典的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在绘制以下值时遇到一些问题:

  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 = '偏移点')

没有注释

  • 通过 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 with None.
  • 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 by hue, 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.
  • The bars are horizontal to accommodate a large number of values.
    • Just increase the figsize height.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆