Colormap fixed middle value

Hej all, for a pcolor plot I have built the ratio of a treatment vs. a control (A./B) and want to plot the resulting pcolor plot with colors according to their value - In this case, 0-1 should always be in a gradient from blue to white, while everything above 1 (differing maxValues) should be in a gradient white to red. Is there a way to "fix" the colorbar so that the white color will always be displayed at value 1 of my data? (or can I use 2 colormaps for this somehow?)

 Respuesta aceptada

Brandon Eidson
Brandon Eidson el 4 de Oct. de 2016

5 votos

You can definitely create a custom color map in MATLAB. One way to do this is by defining the RGB values for your maximum, minimum, and indexed value (your value of "1" is what I am calling the indexed value). You can then create a vector representing RGB values ranging from the minimum to the indexed colors and from the indexed to the maximum colors.
Because the index value may not be the median value of the dataset, the vectors' sizes will need to be adjusted proportionally to where the index falls between the minimum and maximum values.
I have written a script that illustrates this workaround. See if you can apply it to your situation.
L = 10; %number of datapoints
data = 3.6*rand(L); % create example data set with values ranging from 0 to 3.6
indexValue = 1; % value for which to set a particular color
topColor = [1 0 0]; % color for maximum data value (red = [1 0 0])
indexColor = [1 1 1]; % color for indexed data value (white = [1 1 1])
bottomcolor = [0 0 1]; % color for minimum data value (blue = [0 0 1])
% Calculate where proportionally indexValue lies between minimum and
% maximum values
largest = max(max(data));
smallest = min(min(data));
index = L*abs(indexValue-smallest)/(largest-smallest);
% Create color map ranging from bottom color to index color
% Multipling number of points by 100 adds more resolution
customCMap1 = [linspace(bottomcolor(1),indexColor(1),100*index)',...
linspace(bottomcolor(2),indexColor(2),100*index)',...
linspace(bottomcolor(3),indexColor(3),100*index)'];
% Create color map ranging from index color to top color
% Multipling number of points by 100 adds more resolution
customCMap2 = [linspace(indexColor(1),topColor(1),100*(L-index))',...
linspace(indexColor(2),topColor(2),100*(L-index))',...
linspace(indexColor(3),topColor(3),100*(L-index))'];
customCMap = [customCMap1;customCMap2]; % Combine colormaps
colormap(customCMap)
psudo = pcolor(data);
colorbar

4 comentarios

ghastliness
ghastliness el 5 de Oct. de 2016
Editada: ghastliness el 5 de Oct. de 2016
This works perfectly and is exactly what I was looking for! Thank you!
Xiaonan Xing
Xiaonan Xing el 23 de Feb. de 2019
It's such a beautiful work -- thanks a lot Brandon!
Charles Rice
Charles Rice el 25 de Mzo. de 2019
Instead of max(max(A)) you can also use max(A, [], 'all') or max(A(:)). The other methods work no matter the dimensions of your data.
Fizzle
Fizzle el 14 de Nov. de 2021
Thank you Brandon, but I tried this method for a matrix containing negative numbers and it didn't exactly work for me.

Iniciar sesión para comentar.

Más respuestas (1)

Debashish Saha
Debashish Saha el 3 de Jul. de 2018

0 votos

Hi Brandon, does it also work for a vector containing negative values? In my case, it seems that 0 value is not at the exact location / point of white in the color bar. Should one take the absolute of the smallest value to negate the negative number in the vector while determining the index in your code? Thanks in advance. Cheers, DS

Categorías

Más información sobre Color and Styling en Centro de ayuda y File Exchange.

Preguntada:

el 29 de Sept. de 2016

Comentada:

el 14 de Nov. de 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by