How to generate a non-linear colormap/colorbar?

断了今生、忘了曾经 提交于 2019-11-27 05:22:10

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.

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

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.

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');
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!