168 lines
4.9 KiB
Python
Executable file
168 lines
4.9 KiB
Python
Executable file
#!/usr/bin/env python
|
|
|
|
import numpy as np
|
|
import matplotlib.pyplot as plt
|
|
from matplotlib.colors import LinearSegmentedColormap
|
|
|
|
"""
|
|
|
|
Example: suppose you want red to increase from 0 to 1 over the bottom
|
|
half, green to do the same over the middle half, and blue over the top
|
|
half. Then you would use:
|
|
|
|
cdict = {'red': ((0.0, 0.0, 0.0),
|
|
(0.5, 1.0, 1.0),
|
|
(1.0, 1.0, 1.0)),
|
|
|
|
'green': ((0.0, 0.0, 0.0),
|
|
(0.25, 0.0, 0.0),
|
|
(0.75, 1.0, 1.0),
|
|
(1.0, 1.0, 1.0)),
|
|
|
|
'blue': ((0.0, 0.0, 0.0),
|
|
(0.5, 0.0, 0.0),
|
|
(1.0, 1.0, 1.0))}
|
|
|
|
If, as in this example, there are no discontinuities in the r, g, and b
|
|
components, then it is quite simple: the second and third element of
|
|
each tuple, above, is the same--call it "y". The first element ("x")
|
|
defines interpolation intervals over the full range of 0 to 1, and it
|
|
must span that whole range. In other words, the values of x divide the
|
|
0-to-1 range into a set of segments, and y gives the end-point color
|
|
values for each segment.
|
|
|
|
Now consider the green. cdict['green'] is saying that for
|
|
0 <= x <= 0.25, y is zero; no green.
|
|
0.25 < x <= 0.75, y varies linearly from 0 to 1.
|
|
x > 0.75, y remains at 1, full green.
|
|
|
|
If there are discontinuities, then it is a little more complicated.
|
|
Label the 3 elements in each row in the cdict entry for a given color as
|
|
(x, y0, y1). Then for values of x between x[i] and x[i+1] the color
|
|
value is interpolated between y1[i] and y0[i+1].
|
|
|
|
Going back to the cookbook example, look at cdict['red']; because y0 !=
|
|
y1, it is saying that for x from 0 to 0.5, red increases from 0 to 1,
|
|
but then it jumps down, so that for x from 0.5 to 1, red increases from
|
|
0.7 to 1. Green ramps from 0 to 1 as x goes from 0 to 0.5, then jumps
|
|
back to 0, and ramps back to 1 as x goes from 0.5 to 1.
|
|
|
|
row i: x y0 y1
|
|
/
|
|
/
|
|
row i+1: x y0 y1
|
|
|
|
Above is an attempt to show that for x in the range x[i] to x[i+1], the
|
|
interpolation is between y1[i] and y0[i+1]. So, y0[0] and y1[-1] are
|
|
never used.
|
|
|
|
"""
|
|
|
|
|
|
|
|
cdict1 = {'red': ((0.0, 0.0, 0.0),
|
|
(0.5, 0.0, 0.1),
|
|
(1.0, 1.0, 1.0)),
|
|
|
|
'green': ((0.0, 0.0, 0.0),
|
|
(1.0, 0.0, 0.0)),
|
|
|
|
'blue': ((0.0, 0.0, 1.0),
|
|
(0.5, 0.1, 0.0),
|
|
(1.0, 0.0, 0.0))
|
|
}
|
|
|
|
cdict2 = {'red': ((0.0, 0.0, 0.0),
|
|
(0.5, 0.0, 1.0),
|
|
(1.0, 0.1, 1.0)),
|
|
|
|
'green': ((0.0, 0.0, 0.0),
|
|
(1.0, 0.0, 0.0)),
|
|
|
|
'blue': ((0.0, 0.0, 0.1),
|
|
(0.5, 1.0, 0.0),
|
|
(1.0, 0.0, 0.0))
|
|
}
|
|
|
|
cdict3 = {'red': ((0.0, 0.0, 0.0),
|
|
(0.25,0.0, 0.0),
|
|
(0.5, 0.8, 1.0),
|
|
(0.75,1.0, 1.0),
|
|
(1.0, 0.4, 1.0)),
|
|
|
|
'green': ((0.0, 0.0, 0.0),
|
|
(0.25,0.0, 0.0),
|
|
(0.5, 0.9, 0.9),
|
|
(0.75,0.0, 0.0),
|
|
(1.0, 0.0, 0.0)),
|
|
|
|
'blue': ((0.0, 0.0, 0.4),
|
|
(0.25,1.0, 1.0),
|
|
(0.5, 1.0, 0.8),
|
|
(0.75,0.0, 0.0),
|
|
(1.0, 0.0, 0.0))
|
|
}
|
|
|
|
# Now we will use this example to illustrate 3 ways of
|
|
# handling custom colormaps.
|
|
# First, the most direct and explicit:
|
|
|
|
blue_red1 = LinearSegmentedColormap('BlueRed1', cdict1)
|
|
|
|
# Second, create the map explicitly and register it.
|
|
# Like the first method, this method works with any kind
|
|
# of Colormap, not just
|
|
# a LinearSegmentedColormap:
|
|
|
|
blue_red2 = LinearSegmentedColormap('BlueRed2', cdict2)
|
|
plt.register_cmap(cmap=blue_red2)
|
|
|
|
# Third, for LinearSegmentedColormap only,
|
|
# leave everything to register_cmap:
|
|
|
|
plt.register_cmap(name='BlueRed3', data=cdict3) # optional lut kwarg
|
|
|
|
x = np.arange(0, np.pi, 0.1)
|
|
y = np.arange(0, 2*np.pi, 0.1)
|
|
X, Y = np.meshgrid(x,y)
|
|
Z = np.cos(X) * np.sin(Y)
|
|
|
|
plt.figure(figsize=(10,4))
|
|
plt.subplots_adjust(wspace=0.3)
|
|
|
|
plt.subplot(1,3,1)
|
|
plt.imshow(Z, interpolation='nearest', cmap=blue_red1)
|
|
plt.colorbar()
|
|
|
|
plt.subplot(1,3,2)
|
|
cmap = plt.get_cmap('BlueRed2')
|
|
plt.imshow(Z, interpolation='nearest', cmap=cmap)
|
|
plt.colorbar()
|
|
|
|
# Now we will set the third cmap as the default. One would
|
|
# not normally do this in the middle of a script like this;
|
|
# it is done here just to illustrate the method.
|
|
|
|
plt.rcParams['image.cmap'] = 'BlueRed3'
|
|
|
|
# Also see below for an alternative, particularly for
|
|
# interactive use.
|
|
|
|
plt.subplot(1,3,3)
|
|
plt.imshow(Z, interpolation='nearest')
|
|
plt.colorbar()
|
|
|
|
# Or as yet another variation, we could replace the rcParams
|
|
# specification *before* the imshow with the following *after*
|
|
# imshow:
|
|
#
|
|
# plt.set_cmap('BlueRed3')
|
|
#
|
|
# This sets the new default *and* sets the colormap of the last
|
|
# image-like item plotted via pyplot, if any.
|
|
|
|
|
|
plt.suptitle('Custom Blue-Red colormaps')
|
|
|
|
plt.show()
|
|
|