Skip to content Skip to sidebar Skip to footer

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()

enter image description here

Solution 2:

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
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')

enter image description here

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')

enter image description here

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')

enter image description here

Post a Comment for "How To Plot A Dictionary"