Unequal, custom, non-evenly spaced colorbar intervals

48 visualizaciones (últimos 30 días)
Brendan Clark
Brendan Clark el 10 de Mayo de 2021
Editada: DGM el 29 de Mayo de 2024
I have a colorbar ranging from -1000 to 4000 with intervals of 500 throughout. How would I change the colorbar to display intervals so they were spaced 250 from -1000 to 1000, and had an interval of 1000 from 1000 to 4000?
  4 comentarios
Adam Danz
Adam Danz el 10 de Mayo de 2021
Then you must want to change the colormap as well, right? For example, right now there are 6 color levels between 1000 and 4000 and those colors are represented in your plot presumably. If the interval is changed from 500 to 1000 then there will be 3 colors between 1000 and 4000. What color should stay? If you change the colorbar without changing the colormap, then the colorbar will no longer be useful to interpret the color of objects in your plot. Actually, it will be worse than useless - it will be misleading.
So the ultimate goal isn't very clear to me yet.
Himanshu Saxena
Himanshu Saxena el 27 de Ag. de 2022
Hi,
I also have a similar kind of question:
I want to display colorbar with evenly spaced tick intervals (i.e., equal sized blocks) but with unequal difference between tick values. (I don't want a log scale)
I have attached a figure indicating the required format of colorbar.

Iniciar sesión para comentar.

Respuestas (1)

DGM
DGM el 29 de Mayo de 2024
Editada: DGM el 29 de Mayo de 2024
It can be done, but it's annoying to do. A lot of people take shortcuts and represent nonuniform intervals with uniform colorbar segments, but that's just as misleading as using uniformly spaced colors sampled from the parent map, or whichever similar hypothetical Adam noted.
The core of this effort is intervalct(), which I introduced in detail here, including a description of the problems with common solutions:
Since this is a dead question, I'm going to use MIMT tools for my own convenience. They're not strictly necessary for anything here though.
% reconstruct the original colormap at full length.
% the blue half of the CT is cut short.
% rather than tracking down the original map generator,
% i'm just going to regenerate the CT from the red half,
% assuming the red half is full-swing.
CT0 = [218 207 203; 222 188 176; 212 147 125; 197 106 79; 179 64 45; 147 29 43; 107 12 32; 62 8 18]/255;
CTe = ctflop(imtweak(ctflop(CT0),'lchok',[1 1 0.5])); % MIMT
CT0 = [flipud(CTe); CT0];
% interpolate to an adequately oversize map for sampling
x0 = linspace(0,1,16);
xf = linspace(0,1,256);
CT0 = interp1(x0,CT0,xf);
% at this point, CT0 is like any other divergent, smooth map of length 256.
% you could have used twilight(256), brewermap(256,'RdBu'), or turbo(256) or whatever.
% i just felt like doing it the hard way for no good reason.
image(ctflop(CT0))
set(gca,'ydir','normal')
% construct the new interval colormap
% select colors from the base colortable,
% corresponding to the centers of the desired blocks,
% relative to zero and the center of the colortable.
x0 = linspace(-3500,3500,256); % symmetric, to match the base CT symmetry
cen = [(-875:250:875) (1500:1000:3500)]; % the points to sample (bin centers)
CT0 = interp1(x0,CT0,cen); % the sampled colors at the centers of each bin
% these are the breakpoints dividing each bin
bk = [(-1000:250:1000) 2000 3000 4000];
% generate an oversampled arbitrary discrete colortable from the colors in CT0
CT = intervalct(bk,CT0);
image(ctflop(CT))
set(gca,'ydir','normal')
Now let's use the color table we made:
% use the oversampled interval colortable
% fake data on the intended scale
[X Y] = meshgrid(linspace(0,1,500));
Z = rescale(X + Y,-1000,4000);
% plot everything
contourf(X,Y,Z,bk)
% add colorbar with matching ticks
colormap(CT);
cb = colorbar;
cb.Ticks = bk;
caxis(imrange(bk));
The functions imtweak(), ctflop(), and imrange() are from MIMT, though they are clearly not strictly necessary for this task. With the exception of imtweak(), these are simple convenience utilities which can be replaced with inbuilt tools and a bit more verbosity.
The function intervalct() is not currently part of MIMT (yet). You can get it from the link above.

Categorías

Más información sobre Purple en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by