Symmetric (Diverging) log color scale

68 views (last 30 days)
Danielle Lemmon
Danielle Lemmon on 20 Apr 2022
Edited: DGM on 30 Dec 2023
I'm trying to figure out how to make a symmetric (diverging) logarithmic color map/scale. Does anyone have any solutions to go from something like the bottom graph (linear diverging color map) to the top one (logarithmic diverging colormap)? I'd normally start with a color map from cbrewer2 (great download, would highly recommend). But then if I use "set(gca,'ColorScale','log')" it only captures small vs big positive values, not small vs big for both positive vs negative values.
There is a matplotlib function that does exactly this, but having trouble turning it into MATLAB code
https://matplotlib.org/stable/api/_as_gen/matplotlib.colors.SymLogNorm.html?highlight=symlognorm#matplotlib.colors.SymLogNorm

Answers (2)

DGM
DGM on 30 Dec 2023
Edited: DGM on 30 Dec 2023
Here's a shoddy example, but at least it does what's described.
% let A be your data
% note that the data is asymmetric and ends in the middle of a decade
A = linspace(-50, 500, 1000);
% plot A
% i'm going to plot xdata just for sake of giving some scale information
imagesc(signedlog10(A),'xdata',A) % represented in signed log10
% use a symmetric colormap
% MATLAB doesn't really have any good symmetric diverging colormaps
% but this will have to do
colormap(turbo(256))
% get the minimum and maximum value of A
% this needs to be symmetric unless you also make a
% custom asymmetric divergent colormap
crange = [-1 1]*max(abs(imrange(A))); % make symmetric
crange = round(signedlog10(crange)); % you may choose to round to integer values
% set limits for the caxis
caxis(crange); % represented in signed log10
% create ticks, ticklabels
% choose nticks as desired
nticks = 4;
ticklabels = logspace(0,max(crange),nticks);
ticklabels = [-flip(ticklabels) 0 ticklabels]; % make symmetric
% set Ticks and TickLabels
colorbar('Ticks',signedlog10(ticklabels),'TickLabels',ticklabels)
function out = signedlog10(in)
% naive signed-log
%out = sign(in).*log10(abs(in));
% modified continuous signed-log
% see Measurement Science and Technology (Webber, 2012)
C = 0; % controls smallest order of magnitude near zero
out = sign(in).*(log10(1+abs(in)/(10^C)));
end
See also:
and look at the link provided by OP for symlognorm
Note the different approach I used for solving this problem. I leveraged my eyeballs, fingers, and brain to read and comprehend the question and references. I then wrote some code using the aforementioned tools. It's not perfect, generalized, or timely, but it's enough to demonstrate a method similar to the one requested.
While I don't always have a satisfactory answer, I'm not in the habit of asking an AI to generate a code-like collage of text on my behalf and then insincerely pretending that it works without even spending a moment's glance to check that it does.
Providing actual value is less time-efficient than providing the illusion of value. It seems that there are a lot of very efficient users on the forum these days.

Ishu
Ishu on 29 Dec 2023
Hi Danielle,
I understand you want symmetric logarithmic colorbar using "log" property of "ColorScale" but you are getting only positive values.
As the logarithm of a negative number or zero is undefined in the real number system so "set(gca, 'ColorScale', 'log')" only works with positive values. There is a manual approach that you can follow.
% data with both positive and negative values
data = linspace(-200, 100, 1000);
% Display the data
imagesc(data);
colormap('jet'); %set according to your data
% Create a symmetrical log scale for the colorbar
cb = colorbar;
% Set colorbar ticks and labels manually to simulate a symmetrical log scale
caxis([-max(abs(data(:))) max(abs(data(:)))]);
ticks = [-100 -10 -1 1 10 100 1000];
tickLabels = arrayfun(@num2str, ticks, 'UniformOutput', false);
% Apply the ticks and labels to the colorbar
set(cb, 'Ticks', log10(ticks(ticks > 0)), 'TickLabels', tickLabels);
% Adjust the color limits to the data
set(gca, 'CLim', log10([min(ticks(ticks > 0)) max(ticks)]));
For more information on "colorbar" you can follow below documentation:
Hope it helps!
  1 Comment
DGM
DGM on 29 Dec 2023
Yes, a manual approach is needed, but did you even look at the output of the code you pasted?

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!