Nonlinear colour axis on colorbar

조회 수: 16 (최근 30일)
Selwyn
Selwyn 2012년 2월 17일
답변: Constantino 2018년 11월 9일
Hi,
I am trying to make a nonlinear (not logarithmic though) axis on my colorbar. To explain - if I use the following code:
a = rand(20,20);
colormap(jet(5))
conts = [0:1/5:1];
contourf(a,conts,'k:')
cb = colorbar;
caxis([0 1])
set(cb,'YTick',conts)
It produces a correct contourf figure with contour values equally spaced through the colorbar.
However, if I wanted to contour different values, and the change the routine to
a = rand(20,20);
colormap(jet(5))
conts = [0 0.01 0.05 0.9 0.95 1];
contourf(a,conts,'k:')
cb = colorbar;
caxis([0 1])
set(cb,'YTick',conts)
I end up with the colorbar patches not matching the contours I specified and the contours themselves not equally spaced on the colorbar axis, but shown rather as they would be in relation to the distance from zero. My intention is to make the shaded patches match up with the contour intervals I specify, and then have those spaced out neatly along the colorbar regardless of their actual value. The reason I have this is because I have data where the contour values will be something like [-0.1 -0.5 0.5 0.75 0.8 1 10 50 80 85 90:2:100] with each contour chosen for a reason and I need to display it nicely.
Any suggestions?
  댓글 수: 2
Jiro Doke
Jiro Doke 2012년 2월 19일
Do you want the ticks of the color bar to be equally spaced (even if the actual values aren't equally spaced)? Or instead, do you want the color patches to be non-equally spaced to match the actual tick marks? The latter would be more difficult, possibly requiring you to create your own colorbar.
Selwyn
Selwyn 2012년 2월 23일
Hi. I'd like the ticks on the color bar to be equally spaced, even though the actual values arent equally spaced.
The color patches would have to match the ticks too

댓글을 달려면 로그인하십시오.

답변 (3개)

Selwyn
Selwyn 2012년 2월 24일
I solved this problem. To outline the solution:
1) First set your colormap and contour levels so that the number of contours matches the number of colours. (eg: 15 colours & 16 contours)
2) Make a pseudo contour level from 1:length(contours)
3) Scale your data according to the pseudo contour levels (I just found that in Matlab, its easier to scale data than to scale a graphics object like contourf or pcolor.
4) rather use pcolor with 'shading interp' as opposed to contourf (the shading command still gives you a limited number of colours and pcolor works nicely for sparse data)
5) Relabel the yticklabels on the colorbar with your original contour levels.
The exact code is very messy but works - its far better to understand the points above though.
  댓글 수: 1
Milena
Milena 2013년 9월 28일
Hi Selwyn,
I am having the same problem and would like to try your solution. Could you please explain more points 2) and 3)? What do you mean by 'making a pseudo contour level'? And how do you scale your data?
Many thanks, Milena

댓글을 달려면 로그인하십시오.


Stephen Licata
Stephen Licata 2018년 3월 13일
One way of handling this challenge - which I think is what the first answer suggested - is to create a set of colors and treat each color as a separate bin. You would then "translate" data from different value ranges into a sixed, fixed bin number.
For example, you could have a color bar with five colors, as follows: new colors = zeros(5,3);
[041 009 216] scaled to 255 => new colors(1,1:3) = [0.1608 0.0353 0.8471] % dark blue [170 248 255] scaled to 255 => new_colors(2,1:3) = [0.6667 0.9725 1.0000] % light blue [255 255 191] scaled to 255 => new_colors(3,1:3) = [1.0000 1.0000 0.7490] % yellow [248,109,094] scaled to 255 => new_colors(4,1:3) = [0.9725 0.4275 0.3686] % orange [165 000 033] scaled to 255 => new_colors(5,1:3) = [0.6471 0.0000 0.1294] % dark red
Then assign a bin number range of 1 to 5
Then, if you have data that varies from, say, -10 (or less) to + 10.0 (or more), examine each data point and assign it a bin number that corresponds to any non-linear set of ranges.
For example, for data array float X(1000) and corresponding bin assignment integer B(1000)...
if X(n) < -10.0 and X(n) <=-3.0, then B(n) = 1; % dark blue if X(n) >-3.0 and X(n) <-0.50, then B(n) = 2; % light blue if X(n) >=-0.5 and X(n) <= 0.50, then B(n) = 3; % yellow if X(n) > 0.50 and X(n) < 3.0, then B(n) = 4; % orange if X(n) >= 3.0 and X(n) <= 10.0, then B(n) = 5; % dark red
You would then simply plot the B array (not X). When you create your color bar, just scale it from 1 to 5 but add the "real data value" labels of '-10', '-3', '-0.5', '0.5', '3.0', '10';

Constantino
Constantino 2018년 11월 9일
I have the same difficulty, but solved it another way. In short, I plotted with contourf, with the non evenly spaced contours given by a vector. Then, I plotted an empty axis, and made a discrete colorbar (for example jet(4)). The I just changed the colors and the labels of the colorbar ticks. Here is the result. I will read your strategy in detail to see if it is better. To add the second (empty) plot I just put hold on, fakeax=axes, and turned the visible propertie off. The colorbar of the fake invisible axes covers the wrong previous axes.

카테고리

Help CenterFile Exchange에서 Colormaps에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by