How to change the way data is scaled to custom colormap in a scatter plot.

29 views (last 30 days)
Hello,
I've been searching and can't figure out the answer to my specific problem. I am creating scatter plots with over 2K plot points. I am creating 20 different ones that each correspond to a different condition in my data. I am capturing each figure with 'getframe' and then making a movie out of all the plots.
Each plot contains a different range of values, but generally the data spans from a negative value to a positive value. This could be something like -10:8 or -80:65. It's varied throughout the data. I want my colormap to go from red to white for negative values and white to blue for positive values. My custom colormap is basically just RGB values that would produce red to white to blue, but I can't figure out how to apply it to each set of data so that the white is centered around the value closest to 0. I can open up the colormap editor and do it manually by moving the center node, but if I look at the colormap afterward, it doesn't change the values at all. I've looked through the entries in gcf to see if I could figure out what it's changing, but I can't. I've put my code for constructing the images and the colormap below. This is a work in progress, so I know it can be optimized(and obviously some of the variables I refer to are preloaded), but that's for later on. I'm really just trying to get the basics down right now. Any help would be appreciated. Thanks!
loops = 20;
F(loops) = struct('cdata',[],'colormap',[]);
for j = 1:length(loops);
betas = v1betas(:,j);
goodbetas = [betas(goodind),goodind];
sorted = sortrows(goodbetas,1);
plotvals = zeros(length(sorted),2);
for i= 1:length(sorted)
p = sorted(i,2);
plotvals(i,1) = v1ecc(p) * cos(v1ang(p)/180*pi);
plotvals(i,2) = v1ecc(p) * sin(v1ang(p)/180*pi);
end
c = sorted(:,1);
figure;
scatter(plotvals(:,1),plotvals(:,2),40,c,'filled'),colorbar;
colormap(map);
axis([-50 50 -50 50]);
F(j)=getframe(gcf);
close Figure 1;
end
%code for color map:
map = zeros(100,3);
map(1:50,1) = 1;
map(50:100,1) = linspace(1,0,51);
map(50:100,2) = linspace(1,0,51);
map(50:100,3) = 1;
map(1:50,2) = linspace(0,1,50);
map(1:50,3) = linspace(0,1,50);

Answers (1)

Henry Giddens
Henry Giddens on 5 Sep 2016
Hi,
One solution is to set the CLim values for the axis to be equal positive and negative values. The white section of your colormap will then always be centred. This may be suitable if you want to represent the magnitude of the data equally for positive and negative values with respect to their colour.
figure;
scatter(plotvals(:,1),plotvals(:,2),40,c,'filled'),colorbar;
colormap(map);
axis([-50 50 -50 50]);
hAx = gca;
maxLimit = max(abs(c));
hAx.CLim = [-1*maxLimit maxLimit]; %
F(j)=getframe(gcf);
close Figure 1;
Alternatively, you may want to modify the length of the red and blue sections of the colormap depending on the magnitude of the maximum positive and negative values. For example, if the maximum negative value is -5 and the maximum positive value is 10, the red section of the colormap should be twice as long as the blue section. With CLim equal to [-5 10], the white should then be centred at 0.
Henry
  5 Comments
Henry Giddens
Henry Giddens on 6 Sep 2016
Edited: Henry Giddens on 6 Sep 2016
Hi MMM,
Yes, the second solution in my original answer would involve modifying the colormap so that the proportion of the red/blue sections represent the magnitude of your positive/negative data.
So, keeping it simple, with my case of data that ranges from -5:10
map = zeros(99,3);
map(1:33,1) = 1;
map(34:99,1) = linspace(1,0,66);
map(34:99,2) = linspace(1,0,66);
map(34:99,3) = 1;
map(1:33,2) = linspace(0,1,33);
map(1:33,3) = linspace(0,1,33);
C = -5:10;
scatter(1:16,zeros(16,1),40,C,'filled')
colorbar
colormap(map)
Hope that makes a bit more sense? I dont imagine it is the solution you actually want however as it means re calculating your colormap every time you plot the data, and it will look different depending on what the limits of your C data is. (I have also uploaded a figure to my previous comment to illustrate the results you get from normalising your C data).
Henry Giddens
Henry Giddens on 6 Sep 2016
Also, there is one other way in which you could scale the colorbar, by setting the CAxis limits to be equal, and then clipping the colorbar limits to your data range:
C = -5:10;
scatter(1:16,zeros(16,1),40,C,'filled')
hAx = gca;
cbar = colorbar;
colormap(map) %your original map...
hAx.CLim = [-10 10];
cbar.Limits = [-5 10];

Sign in to comment.

Categories

Find more on Colormaps in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!