I have a normalised range of values in a numpy array, so 0 to 1, let's call this normal_array.
normal_array = np.array([0.0, 0.3, 0.356, 0.49, 0.64, 0.784, 1.0])
I need to create another numpy array which contains the rgb values of a colour ramp, let's call this colour_array. How do I map the RGB values from a colour ramp to the normal_array?
It would be great if I could use an existing colour ramp like these from matplotlib; https://matplotlib.org/stable/tutorials/colors/colormaps.html
How do you map the 0-1 values to rgb values from a colour ramp?
Related
I have the following:
df.groupby(['A', 'B'])['time'].mean().unstack().plot()
This gives me a line graph like this one:
The circles in the plot indicate data points. The values on x-axis are the values of A which are discrete (100, 200 and 300). That is, I only have data points on the 100th, 200th and 300th point on the x-axis. Pandas/Matplotlib adds the intermediate values on the x-axis (125, 150, 175, 225, 250 and 275) that I don't want.
How can I plot and tell Pandas not to add the extra values on the x-axis?
Matplotlib x axis tick locators
You're looking for tick locators
import matplotlib.ticker as ticker
df = pd.DataFrame({'y':[1, 1.75, 3]}, index=[100, 200, 300])
ax = df.plot(legend=False)
ax.xaxis.set_major_locator(ticker.MultipleLocator(100))
Let's say I have a vector containing integers from the set [1,2,3]. I would like to create a colormap in which 1 always appears as blue, 2 always appears as red, and 3 always appears as purple, regardless of the range of the input data--e.g., even if the input vector only contains 1s and 2s, I would still like those to appear as blue and red, respectively (and purple is not used in this case).
I've tried the code below:
This works as expected (data contains 1, 2 and 3):
cmap = colors.ListedColormap(["blue", "red", "purple"])
bounds = [0.5,1.5,2.5,3.5]
norm = colors.BoundaryNorm(bounds, cmap.N)
data = np.array([1,2,1,2,3])
sns.heatmap(data.reshape(-1,1), cmap=cmap, norm=norm, annot=True)
Does not work as expected (data contains only 1 and 2):
cmap = colors.ListedColormap(["blue", "red", "purple"])
bounds = [0.5,1.5,2.5,3.5]
norm = colors.BoundaryNorm(bounds, cmap.N)
data = np.array([1,2,1,2,2])
sns.heatmap(data.reshape(-1,1), cmap=cmap, norm=norm, annot=True)
In the first example, 1 appears as blue, 2 appears as red and 3 appears as purple, as desired.
In the second example, 1 appears as blue and 2 appears as purple, while red is not used.
Not completely sure, but I think this minimal example solves your problem. Here, I've taken an actual colormap and edited it to produce a smaller version of it. Hope it helps!
#0. Import libraries
#==============================
import matplotlib
import matplotlib.pyplot as plt
from matplotlib import colors
import seaborn as sns
import numpy as np
#==============================
#1. Create own colormap
#======================================
#1.1. Choose the colormap you want to
#pick up colors from
source_cmap=matplotlib.cm.get_cmap('Set2')
#1.2. Choose number of colors and set a step
cols=4;step=1/float(cols - 1)
#1.3. Declare a vector to store given colors
cmap_vec=[]
#1.4. Run from 0 to 1 (limits of colormap)
#stepwise and pick up equidistant colors
#---------------------------------------
for color in np.arange(0,1.1,step):
#store color in vector
cmap_vec.append( source_cmap(color) )
#---------------------------------------
#1.5. Create colormap with chosen colors
custom_cmap=\
colors.ListedColormap([ color for color in cmap_vec ])
#====================================
#2. Basic example to plot in
#======================================
A = np.matrix('0 3; 1 2')
B=np.asarray(A)
ax=sns.heatmap(B,annot=True,cmap=custom_cmap)
plt.show()
#======================================
In matplotlib, I would like to change colorbar's color in some particular value interval. For example, I would like to change the seismic colorbar, to let the values between -0.5 and 0.5 turn white, how can I do this?
thank you very much
You basically need to create your own colormap that has the particular features you want. Of course it is possible to make use of existing colormaps when doing so.
Colormaps are always ranged between 0 and 1. This range will then be mapped to the data interval. So in order to create whites between -0.5 and 0.5 we need to know the range of data - let's say data goes from -1 to 1. We can then decide to have the lower (blues) part of the seismic map go from -1 to -0.5, then have white between -0.5 and +0.5 and finally the upper part of the seismic map (reds) from 0.5 to 1. In the language of a colormap this corresponds to the ranges [0,0.25], [0.25, 0.75] and [0.75,1]. We can then create a list, with the first and last 25% percent being the colors of the seismic map and the middle 50% white.
This list can be used to create a colormap, using matplotlib.colors.LinearSegmentedColormap.from_list("colormapname", listofcolors).
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
n=50
x = 0.5
lower = plt.cm.seismic(np.linspace(0, x, n))
white = plt.cm.seismic(np.ones(100)*0.5)
upper = plt.cm.seismic(np.linspace(1-x, 1, n))
colors = np.vstack((lower, white, upper))
tmap = matplotlib.colors.LinearSegmentedColormap.from_list('terrain_map_white', colors)
x = np.linspace(0,10)
X,Y = np.meshgrid(x,x)
z = np.sin(X) * np.cos(Y*0.4)
fig, ax = plt.subplots()
im = ax.imshow(z, cmap=tmap)
plt.colorbar(im)
plt.show()
For more general cases, you may need a color normalization (using matplotlib.colors.Normalize). See e.g. this example, where a certain color in the colormap is always fixed at a data value of 0, independent of the data range.
I have a numpy array in the shape [n_samples,color_channels*time_window, width,height] storing the data for seven frames of color image, I want to reshape it to [n_samples, color_channels, time_window,width,height] how can I do it?
First: shapes are tuples. You may try that, assuming A is your original array:
B = np.reshape(A, (n_samples, color_channels, time_window, width, -1))
print(B.shape)
I have a 2d numpy array obtained by reading from an image. The unique values of the array are 0, 1, and 2. I want to plot the image showing unique colors red, green, and blue for the values 0,1, and 2 respectively.
plt.imshow(data, cmap=colors.ListedColormap(['red'])
How would you do it?
from matplotlib.colors import from_levels_and_colors
cmap, norm = from_levels_and_colors([0,1,2,3],['red','green','blue'])
plt.imshow(data, cmap=cmap, norm=norm)