简体   繁体   中英

Matplotlib: How to assign increasing shade of colors according to the size of text in a plot?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM