Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change a 'LinearSegmentedColormap' to a different distribution of color?

I am trying to make a color map that 'favors' lower values, i.e. it takes longer to get out of the darker color to get to the light color. At the moment I am using this as the colormap:

cmap = clr.LinearSegmentedColormap.from_list('custom blue', ['#ffff00','#002266'], N=256)

I am plotting this around a cylinder to see the effect (see code for cylinder at the end of the post), this is what happens when you run the code:

enter image description here

As you can see this is very 'linear'. The color starts changing about halfway along the cylinder. Is there a way to increase the threshold for when the colors start to change rapidly? I.e. I want only very high numbers to have the brightest level of yellow. Thanks.

from matplotlib import cm
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from scipy.linalg import norm
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import numpy as np
import math
import mpl_toolkits.mplot3d.art3d as art3d
import matplotlib.colors as clr


fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')



origin = [0,0,0]
#radius = R
p0 = np.array(origin)
p1 = np.array([8, 8, 8])
origin = np.array(origin)
R = 1

#vector in direction of axis
v = p1 - p0
#find magnitude of vector
mag = norm(v)
#unit vector in direction of axis
v = v / mag
#make some vector not in the same direction as v
not_v = np.array([1, 0, 0])
if (v == not_v).all():
not_v = np.array([0, 1, 0])
#make vector perpendicular to v
n1 = np.cross(v, not_v)
#normalize n1
n1 /= norm(n1)
#make unit vector perpendicular to v and n1
n2 = np.cross(v, n1)
#surface ranges over t from 0 to length of axis and 0 to 2*pi
t = np.linspace(0, mag, 600)
theta = np.linspace(0, 2 * np.pi, 100)
#use meshgrid to make 2d arrays
t, theta = np.meshgrid(t, theta)
#generate coordinates for surface
X, Y, Z = [p0[i] + v[i] * t + R * np.sin(theta) * n1[i] + R * np.cos(theta) *     n2[i] for i in [0, 1, 2]]

#THIS IS WHERE THE COLOR MAP IS

cmap = clr.LinearSegmentedColormap.from_list('custom blue',     ['#ffff00','#002266'], N=256)
col1 = cmap(np.linspace(0,1,600)) # linear gradient along the t-axis
col1 = np.repeat(col1[np.newaxis,:, :], 100, axis=0) # expand over the theta-            axis

ax.plot_surface(X, Y,Z, facecolors = col1, shade = True,edgecolors = "None",        alpha = 0.9, linewidth = 0)
ax.view_init(15,-40)

plt.show()
like image 387
fosho Avatar asked Jul 01 '16 14:07

fosho


People also ask

What is CMAP =' viridis?

( cmaps.viridis is a matplotlib.colors.ListedColormap ) import matplotlib.pyplot as plt import matplotlib.image as mpimg import numpy as np import colormaps as cmaps img=mpimg.imread('stinkbug.png') lum_img = np.flipud(img[:,:,0]) imgplot = plt.pcolormesh(lum_img, cmap=cmaps.viridis)

How do you normalize a Colorbar in Python?

will map the data in Z linearly from -1 to +1, so Z=0 will give a color at the center of the colormap RdBu_r (white in this case). Matplotlib does this mapping in two steps, with a normalization from the input data to [0, 1] occurring first, and then mapping onto the indices in the colormap.

How do you reverse a colormap in Python?

We can reverse the colormap of the plot with the help of two methods: By using the reversed() function to reverse the colormap. By using “_r” at the end of colormap name.


1 Answers

When making colormaps with LinearSegmentedColormap.from_list, you can supply a list of tuples of the form (value, color) (as opposed to simply a list of colors) where the values correspond to the relative positions of colors. The values must range from 0 to 1 so you will have to supply an intermediate color. In your case I might try this,

cmap = clr.LinearSegmentedColormap.from_list('custom blue', 
                                             [(0,    '#ffff00'),
                                              (0.25, '#002266'),
                                              (1,    '#002266')], N=256)

and tweak color/value until satisfied. Credit goes to https://stackoverflow.com/a/25000108/5285918

enter image description here

like image 51
lanery Avatar answered Oct 11 '22 09:10

lanery