Nonlinear colormap for data that diverges

36 visualizzazioni (ultimi 30 giorni)
Jared Erb
Jared Erb il 10 Feb 2024
Commentato: Voss il 11 Feb 2024
I have data that goes through divergences where the Z value goes from approximately -4000 to 4000 very rapidly in certain regions, but the vast majority of the data is near zero. In the picture below, to be able to see what is going on I had to scale most of the color values to near zero to properly see what is happening. But in doing so, most of the colors are in the tiny sliver near zero and the red and blue take up the rest. I would like to nonlinearly scale the colorbar to be able to see all of the colors being used and greatly shrink the red and blue color part of the bar, with leaving the raw data as is if possible. It would also be nice if the colorbar ticks would vary nonlinear as well, instead of being forced to have a set number between consecutive ticks.
%Simple Model of divergent data
X = linspace(-2,2,501) + 0.002;
Y = linspace(-2,2,501) + 0.002;
%Function with Positive and Negative Divergence, and most values near 0
Z = zeros(501,501);
for i=1:length(X)
for j=1:length(Y)
Z(i,j) = 1/((X(i) - 1)^2 + (Y(j) - 1)^2) - 1/((X(i) + 1)^2 + (Y(j) + 1)^2) + 5*(cos(X(i))+sin(Y(i)));
end
end
%Setting the colormap
factor = 0.3;
cmap = jet(1000);
map = 999*rescale(1000./(1+exp(-factor*([1:1000]-500))));
cmap2 = cmap(1+fix(map),:);
figure('Position',[200,100,1500,730]);
ax=axes;
[X,Y] = meshgrid(X,Y);
surf(X,Y,Z,'linestyle','none');
a = colorbar;
set(ax,'colormap',cmap2)
view([0,90])

Risposta accettata

Voss
Voss il 10 Feb 2024
Modificato: Voss il 11 Feb 2024
How about something like this:
%Simple Model of divergent data
X = linspace(-2,2,801) + 0.002;
Y = linspace(-2,2,501) + 0.002;
%Function with Positive and Negative Divergence, and most values near 0
Z = 1./((X - 1).^2 + (Y.' - 1).^2) - 1./((X + 1).^2 + (Y.' + 1).^2) + 5*(cos(X)+sin(Y.'));
Z_scaled = sign(Z).*log10(1+abs(Z));
figure('Position',[200,100,1500,730]);
surf(X,Y,Z_scaled,'LineStyle','none')
view(2)
colormap(jet(1000))
cb = colorbar();
tl = [-10.^(5:-1:1) 0 10.^(1:5)];
cb.Ticks = sign(tl).*log10(1+abs(tl));
cb.TickLabels = tl;
Edited to use Z_scaled = sign(Z).*log10(1+abs(Z)); instead of Z_scaled = sign(Z).*log10(abs(Z));
  6 Commenti
Jared Erb
Jared Erb il 11 Feb 2024
Yes, this is exactly what I wanted! Thank you so very much for all your help!

Accedi per commentare.

Più risposte (1)

Morgan
Morgan il 10 Feb 2024
Would something like this work for you?
% CALCULATE MESHGRID
xa = linspace(-2,2,501) + 0.002;
ya = linspace(-2,2,501) + 0.002;
[X,Y] = meshgrid(xa,ya);
% CALCULATE Z
Z = 1./((X - 1).^2 + (Y - 1).^2) - 1./((X + 1).^2 + (Y + 1).^2) + 5*(cos(X)+sin(Y));
% SCALE Z
ZS = sign(Z).*abs(log10(Z));
surf(X,Y,ZS)
axis equal tight
shading interp
colorbar;
view([ 0 90 ])
  3 Commenti
Morgan
Morgan il 10 Feb 2024
Something like this, then?
Jared Erb
Jared Erb il 10 Feb 2024
Unforunately that doesn't work for negative values, but I would like to have a nonlinearity that isn't log based, as I couldn't get any log scaling to work correctly.

Accedi per commentare.

Prodotti


Release

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by