How To Plot A Dictionary
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.
Solution 1:
Here is how you can do that with matplotlib
:
import matplotlib.pyplot as plt
from numpy import random
mydict={'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']}
for k,l in mydict.items():
labeled = False
c=random.rand(3,)
for v in l:
if labeled:
plt.bar(v,len([d for d in l if d==v]),color=c)
else:
plt.bar(v,len([d for d in l if d==v]),label=k,color=c)
labeled = True
plt.legend()
plt.show()
Solution 2:
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
0122.0230.0542.0134.01121.2230.0542.0134.02132.0230.0540.0 NaN
3132.0230.0 NaN NaN
4144.0 NaN NaN NaN
5144.5 NaN NaN NaN
6144.0 NaN NaN NaN
7150.0 NaN NaN NaN
8150.5 NaN NaN NaN
9150.5 NaN NaN NaN
10150.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 uniquefor 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 uniquefor 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')
Post a Comment for "How To Plot A Dictionary"