As soon as you get some data, you may want to create a plot and see what it looks like. You may even want to share your findings with your colleagues in a way that is easiest for them to understand.
For these reasons, you will eventually need to choose the colors for you plot in order to summarize some information. A pre defined set of colors is called a color map, or cmap
for short.
Color maps are useful because it saves you from picking colors by coloring your plot automatically. In some areas there are standard color maps, but usually, when unsure about what color to use, you just go with jet
or grayscale
.
To be honest, I find jet
colors to be very appealling because it cleary shows low valleys in blue and the high peaks in red, with the values in between as some shades of yellowish green. The contrast feels great and the colors are shiny.
Just until recently I came across this article, which shows why jet
color map is a bad idea. He explains in a very detailed way why jet
color map may be highlighting some regions that are not supposed to. At first, I thought it was just some fancy concepts for designers and useless for engineers, so I kept using jet
.
Until I started to visualize face images - which, in fact, humans are extremely good at noticing subtleties.
Now, it all make sense, and I decided to share why.
You can still use jet
color map if you want, but I created this tutorial to uncover what problems you might face when using it.
In [1]:
%matplotlib inline
import numpy as np #as always
import matplotlib.pyplot as plt #to visualize things
import urllib #to download our dataset
from PIL import Image #to manipulate images
from StringIO import StringIO # these libraries are used to unzip
from zipfile import ZipFile # and store images in memory
from pylab import rcParams #just so I can resize my resulting images
import warnings #ignore warnings
warnings.filterwarnings('ignore')
rcParams['figure.figsize'] = 15, 15
In [2]:
url1 = 'http://fei.edu.br/~cet/frontalimages_spatiallynormalized_part1.zip'
url2 = 'http://fei.edu.br/~cet/frontalimages_spatiallynormalized_part2.zip'
zip_files = [urllib.urlretrieve(url1)[0],urllib.urlretrieve(url2)[0]]
archive = [ZipFile(zip_files[0],'r'),ZipFile(zip_files[1],'r')]
face_db = []
for name in archive[0].namelist()+archive[1].namelist():
try:
face = Image.open(StringIO(archive[0].read(name)))
except:
face = Image.open(StringIO(archive[1].read(name)))
face_db.append(np.array(face))
face_db = np.array(face_db)
In [3]:
np.random.seed(16)
f, axarr = plt.subplots(1,5)
for i in range(5):
axarr[i].imshow(face_db[np.random.randint(face_db.shape[0])],cmap='gray')
axarr[i].axis('off')
In [4]:
np.random.seed(16)
f, axarr = plt.subplots(1,5)
for i in range(5):
axarr[i].imshow(face_db[np.random.randint(face_db.shape[0])],cmap='jet')
axarr[i].axis('off')
After these two examples, hopefully it's now clear to why some people say some non-uniform color maps (jet
) are bad. In this example, we can clearly see that some important facial features, such as wrinkles and moles are almost gone, whereas some other facial regions are unnecessarily highlighted.
There are dozens of other options for color maps. The code below shows some of the color maps available on matplotlib
. Some of them are uniform and some aren't. Nevertheless, all of them has an application that makes each of them suitable.
Can you identify which are uniform and which aren't?
In [5]:
np.random.seed(16)
face = np.random.randint(199)
cmaps = [cmap for cmap in plt.colormaps() if not cmap.endswith("_r")]
k=0
f, axarr = plt.subplots(7,12)
for j in range(7):
for i in range(12):
axarr[j,i].set_title(cmaps[k], fontsize=10)
axarr[j,i].imshow(face_db[face],cmap=cmaps[k])
axarr[j,i].axis('off')
k+=1