How to generate a non-linear colormap/colorbar?

2019-01-08 00:46发布

问题:

I would like to show a non-uniform colorbar as in the first picture. I have tried the code below. 'mycamp4' is a colormap manually saved. The result is shown as the second figure. The number 0.1 and 1.5 will be too closed too see. How can I make the colorbar like in the first picture?

v = [0.1 1 1.5 5 7.5 10 30];
v_2 = [0.1 1.5 5 7.5 10 30];
contourf(X,Y,pdf_normal',v);
h = colorbar;
load('MyColormaps','mycmap4');
set(gcf,'Colormap',mycmap4);
set(h, 'YTick', v_2)

Picture 1:

Picture 2:

回答1:

Here a step by step explanation.

First consider the following example:

[X,Y,Z1] = peaks;

figure(1)
[~,h1] = contourf(X,Y,Z1,20);
a1 = colorbar;
colormap(jet)
caxis([-6,6])

which will give you the following plot:

It has linear data and a linear colormap. Now I want to scale the Z-Data to get it non-linear like in your case. I chose a simple squaring of the data.

Z2 = get(h1,'ZData');
scalefactor = @(x) sign(x).*x.^2;
Z2 = scalefactor(Z2);

Thats the actual example data, similar to yours:

figure(2)
[~,h2] = contourf(X,Y,Z2,20);
a2 = colorbar;
colormap(jet)
caxis([-6^2,6^2])

Now we have non-linear data, but still a linear colormap and colorbar.

Until now everything was to generate example data similar to yours.


Now the actual answer:

Get the data of your plot:

Z3 = get(h2,'ZData');

and scale it with a relation you hopefully know more or less:

descalefactor = @(x) sign(x).*abs(x).^(1/2);
Z3 = descalefactor(Z3);

Plot that scaled data:

figure(3)
[~,h3] = contourf(X,Y,Z3,20);
a3 = colorbar;
colormap(jet)
caxis([-6,6])

get the Y-Ticks and scale it with the inverse function, like your data:

ticks = get(a3,'YTick');
ticks = scalefactor(ticks);

set these inversly scaled colorbar ticks:

set(a3,'YTickLabel',ticks)

and you finally get a seemingly linearized plot (but you could just backup your non-linear data from before), with a with non-linear colormap and colorbar ticks.

As expected, the plot looks the same like in the first the example, but with a scaled colorbar axis.

If you don't have any functional relationship, try to get one, e.g. with the curve fitting toolbox.



回答2:

You can customize the colormap and the ticks in the colorbar, but the colorbar itself is based on linear intervals and you can't change that.

There's a workaround though.

lets say you want your colorbar like that in picture 1 with N nonlinear intervals (e.g. color_limits = [1 2 20], if N=2). you have to:

1) define another variable for your data. e.g.

data2 = nan(size(data));
for i=1:N
   b = data>color_limits(i) & data>=color_limits(i+1);
   data2(b) = i-0.5;
end

Basically you are binning data, using the intervals in color_limits, into a different variable data2 that you will display

2) make your image of data2

3) define the colorbar limits: caxis([0 N])

4) define a colormap with N colors, e.g. colormap(jet(N))

5) customize the ticks in the colorbar



回答3:

When you try doc colorbar you will find a reference to the colormap. And after trying doc colormap they basically give 3 options to set the color map.

  1. Enter a map (for example one obtained by get or one designed earlier, this is what you tried)
  2. Select a built-in colormap with the Property Editor.
  3. Use the Colormap Editor, accessible from Edit > Colormap on the figure menu.

@horchler already mentioned it, but I assume you have not heard about the colormap editor before. Hence I would suspect that option 3 is most suitable for you.



回答4:

one can try Recolor_contourf. It has two more functions and easy to use. In its help the example given as follows. The function is submitted by me. let me know if face any issue

X=1:10;Y=1:10;
C=rand(10,10)*150;
c=colormap(jet(7));
L=[10 20 50 60 70 100];
[cdd hc]=contourf(X,Y,C,[-5 L]);
Recolor_contourf(hc,c,L,'vert');