I have a bunch of words frequencies:
words = ['an', 'apple', 'in', 'a', 'tree']
counts = [23, 12, 45, 20, 9]
How can I plot the words in matplotlib according to their values and also color changing smoothly (for example cm.Blues) ?
My attempt is this:
import numpy as np
import matplotlib.pyplot as plt
plt.rc('font',**{'size':20, 'family':'fantasy'})
from collections import Counter
from matplotlib import colors as mcolors
words = ['an', 'apple', 'in', 'a', 'tree']
counts = [23, 12, 45, 20, 9]
plt.figure(figsize=(8,8))
c = list(mcolors.CSS4_COLORS.values())
for i in range(len(words)):
x = np.random.uniform(low=0, high=1)
y = np.random.uniform(low=0, high=1)
plt.text(x, y, words[i],
size=counts[i]*2,
rotation=np.random.choice([-90, 0.0, 90]),
color=c[np.random.randint(0,len(c))])
plt.setp(plt.gca(), frame_on=False, xticks=(), yticks=())
plt.show()
There are random colors.
How can we assign increasing shade of color to make this picture more intuitive?
CSS4_colors are HTML colors defined using an hex code. This is not the best choice if you want to change the saturation or brightness. You may want to use the HSV color model.
Thus you have to convert your color to hsv and then change either s or v according to your word count.
import numpy as np
import matplotlib.pyplot as plt
plt.rc('font',**{'size':20, 'family':'fantasy'})
from matplotlib import colors as mcolors
words = ['an', 'apple', 'in', 'a', 'tree']
counts = [23, 12, 45, 20, 9]
maxcounts = max(counts)
sat = [c / maxcounts for c in counts]
plt.figure(figsize=(8,8))
# convert colors to HSV
css4_colors = list(mcolors.CSS4_COLORS.values())
ncolors = len(c)
rgb = [mcolors.to_rgb(c) for c in css4_colors]
hsv = [mcolors.rgb_to_hsv(c) for c in rgb]
for i in range(len(words)):
x = np.random.uniform(low=0, high=1)
y = np.random.uniform(low=0, high=1)
# select a color
icolor = np.random.randint(0, ncolors)
color = hsv[icolor]
color[1] = sat[i] # here change saturation, index 1 or brightness, index 2 according to the counts list
plt.text(x, y, words[i],
size=counts[i] * 2,
rotation=np.random.choice([-90, 0.0, 90]),
color=mcolors.hsv_to_rgb(color)) # don't forget to get back to rgb
plt.setp(plt.gca(), frame_on=False, xticks=(), yticks=())
plt.show()
EDIT
Ok, this is another version where you select a hue color (between 0 and 1), the brightness and you change only the saturation.
Depending on what you want, you can change the brightness according to the counts and keep the saturation constant.
import numpy as np
import matplotlib.pyplot as plt
plt.rc('font',**{'size':20, 'family':'fantasy'})
from matplotlib import colors as mcolors
words = ['an', 'apple', 'in', 'a', 'tree']
counts = [23, 12, 45, 20, 9]
maxcounts = max(counts)
sat = [c / maxcounts for c in counts]
plt.figure(figsize=(8,8))
# select a hue value => define the color
hue = 0.6
# choose a brightness
brightness = 1
for i in range(len(words)):
x = np.random.uniform(low=0, high=1)
y = np.random.uniform(low=0, high=1)
# select a color
color = (hue, sat[i], brightness)
plt.text(x, y, words[i],
size=counts[i] * 2,
rotation=np.random.choice([-90, 0.0, 90]),
color=mcolors.hsv_to_rgb(color)) # don't forget to get back to rgb
plt.setp(plt.gca(), frame_on=False, xticks=(), yticks=())
plt.show()