How do I create a logarithmic scale colormap or colorbar?

I need to color 'surf' plots on a log scale and subsequently displace the log-based colorbar.

 Accepted Answer

Please follow the steps below to create a log colorbar in a 'surf' plot:
 
% Plot the surface plot
[X, Y] = meshgrid(1:0.5:10,1:20);
Z = sin(X) + cos(Y);
figure;
surf(X, Y, Z)
% Show the colorbar
colorbar
% Set the log colobar
set(gca,'ColorScale','log')
Note: This feature was introduced in MATLAB R2018a.
For more information, refer to the "Color and Transparency Maps" section of the Axes Properties documentation:

6 Comments

How does MATLAB determine the color axis limits when using log-transformed color axes? In the following code, both caxis limits will be the same.
A = random(makedist('Lognormal',5,1),100,100);
subplot(1,2,1)
imagesc(A); set(gca,'colorscale','log'); colorbar
log10(caxis)
subplot(1,2,2)
imagesc(log10(A)); colorbar
caxis
However, if I run the following lines
A = random(makedist('Lognormal',5,1),100,100);
subplot(1,2,1)
imagesc(A.^5); set(gca,'colorscale','log'); colorbar
log10(caxis)
subplot(1,2,2)
imagesc(log10(A.^5)); colorbar
caxis
both caxis are different.
As a demonstration...
Notice that the lower bounds of xaxis for the A.^5 case are 5e16 instead of 557, I do not currently have an explanation for this.
format long g
A = random(makedist('Lognormal',5,1),100,100);
subplot(2,2,1)
imagesc(A); set(gca,'colorscale','log'); colorbar
log10(caxis)
ans = 1×2
0.549218064964577 4.14936014310785
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
subplot(2,2,2)
imagesc(log10(A)); colorbar
caxis
ans = 1×2
0.549218064964577 4.14936014310785
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
subplot(2,2,3)
B = A.^5;
imagesc(B); set(gca,'colorscale','log'); colorbar
[minB, maxB] = bounds(B,'all')
minB =
557.301644804751
maxB =
5.58213988624748e+20
caxis
ans = 1×2
1.0e+00 * 5.58213988624748e+16 5.58213988624748e+20
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
log10(caxis)
ans = 1×2
16.7468007155392 20.7468007155392
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
subplot(2,2,4)
imagesc(log10(B)); colorbar
caxis
ans = 1×2
2.74609032482288 20.7468007155392
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
It looks like the algorithm for automatic caxis might be approximately:
Take the upper bound of the image. Divide the upper bound by 1e4 . If the lower bound of the data is above that, use the lower bound of the data as the lower bound of caxis; otherwise use the bound divided by 1e4 as the lower bound of the caxis.
The lower bound of the caxis does not come out as exactly 1e4 lower in all cases; I do not currently know what the adjustment is.
Hi @Walter Roberson, thank you! That is very helpful. It'll be great if @MathWorks Support Team could comment on this, too.
Thank you for pointing out this behavior of "colorbar" limits. A request has been made to the MathWorks development team to document specifically how the limits of a "colorbar" are determined.

Sign in to comment.

More Answers (2)

4 Comments

I'm pretty sure it was introduced in 2018a
Another approach for R2018a is:
cb = colorbar();
cb.Ruler.Scale = 'log';
cb.Ruler.MinorTick = 'on';
In theory this should also work in R2017b (and perhaps other releases), but in R2017b you will get an warning message,
Warning: Error updating ColorBar.
DataSpace or ColorSpace transform method failed
You can tell by the wording of the official answer that it was written for an older version of MATLAB.
Hi Kristoffer Walker,
If you still need assistance with this issue, please create a MathWorks Technical Support Case. We would be happy to help you out.

Sign in to comment.

Try the following:
% let A be your data
A = 100*rand(100,100);
% plot log10 of A
pcolor(log10(A))
% get the minimum and maximum value of A
c1 = min(min(A));
c2 = max(max(A));
% set limits for the caxis
caxis([log10(c1) log10(c2)]);
% preallocate Ticks and TickLabels
num_of_ticks = 5;
Ticks = zeros(1,num_of_ticks);
TickLabels = zeros(1,num_of_ticks);
% distribute Ticks and TickLabels
for n = 1:1:num_of_ticks
Ticks(n) = log10(round(c2)/num_of_ticks*n);
TickLabels(n) = round(c2)/num_of_ticks*n;
end
% set Ticks and TickLabels
colorbar('Ticks',Ticks,'TickLabels',TickLabels)

Products

Release

R2018a

Community Treasure Hunt

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

Start Hunting!