How do I change the color distribution in contourf?

47 views (last 30 days)
I am trying to make a filled contour as in the following MWE.
%% Data aa is on the z - axis
aa = [190 201 196 187 202 205 192 200 215 207 201 222 224 206 229 248 235 291 321 317 281 191 202 197 188 203 206 194 202 216 208 203 224 227 208 235 255 241 4898 4898 4898 4898];
[x,y] = meshgrid([-10 -6 -2 2 6 10],[15 20 25 30 35 40 45]); %Meshgrid for x & y for the contour
%% Create the meshgrid for z for plotting
z = size(x);
z = zeros(size(x));
for i=1:6
z(:,i) = aa(7*(i-1)+1:7*i); % 7 because thats how my data is distributed in the array "aa"
end
%% Create the contour
contourf(y,x,z,30,"LineStyle","none")
h = colorbar;
But due to the large values in the array "aa" the whole plot is getting poloarized towards it.
Is there a way in which I can make the contour plot of the rest values without having the color gradient being affected by the large values and then denote the large values with red spot(red showing higher value in the contour)?
  2 Comments
Dhruv Thakkar
Dhruv Thakkar on 18 Jan 2022
Hey @KSSV,
Thank you for the suggestion. Maybe I didn't frame my question correctly. if I use caxis I am still losing the information and variation in the lower data range.

Sign in to comment.

Accepted Answer

DGM
DGM on 18 Jan 2022
Edited: DGM on 18 Jan 2022
This probably isn't exactly what you want, but I think that an inpainting+marker approach would be visually misleading. In this example, I simply omit the extreme values by replacing them with NaN. The result is that no interpolation is performed between said points and their neighbors.
% Data aa is on the z - axis
aa = [190 201 196 187 202 205 192 200 215 207 201 222 224 206 229 248 235 291 321 317 281 191 202 197 188 203 206 194 202 216 208 203 224 227 208 235 255 241 4898 4898 4898 4898];
[x,y] = meshgrid([-10 -6 -2 2 6 10],[15 20 25 30 35 40 45]); %Meshgrid for x & y for the contour
% Create the meshgrid for z for plotting
z = reshape(aa,size(x));
% omit extreme values
z(z>500) = NaN;
% Create the contour
contourf(y,x,z,30,"LineStyle","none")
h = colorbar;
Note the use of reshape().
Alternatively, you could just constrain everything to a fixed z interval. Note that you have to constrain both caxis() and the levels used by contourf().
% Data aa is on the z - axis
aa = [190 201 196 187 202 205 192 200 215 207 201 222 224 206 229 248 235 291 321 317 281 191 202 197 188 203 206 194 202 216 208 203 224 227 208 235 255 241 4898 4898 4898 4898];
[x,y] = meshgrid([-10 -6 -2 2 6 10],[15 20 25 30 35 40 45]); %Meshgrid for x & y for the contour
% Create the meshgrid for z for plotting
z = reshape(aa,size(x));
% Create the contour
clim = [min(z(:)) 320]; % pick some upper limit
v = linspace(clim(1),clim(2),30);
contourf(y,x,z,v,"LineStyle","none")
h = colorbar;
caxis(clim) % pick some upper limit

More Answers (1)

Real User
Real User on 4 Jan 2023
Edited: Real User on 4 Jan 2023
Using either of the following two codes you seem to get a better solution - you can specify the zlevels for colors, too. They have 5-star reviews. The upper one has more of them:
If you don't want to use such a code, then the following is the simplest way of getting a decent result (I suggest removing the "LineStyle","none" for clarity):
contourf(y,x,z,30,"LineStyle","none")
clim([zzmin zzmax])
That clim([zzmin zzmax]) reserves all the colors for the height values that lie between zzmin and zzmax.
(caxis is the same as clim, but clim is now recommended.)
So use that with zzmax small enough to concentrate the whole "color resolution" for heights in [zzmin, zzmax]. E.g.,
zmin = min(aa);
zmax = max(aa);
zzmin = zmin;
zzmax = zmin + (zmax-zmin)/3;
The drawback is that anything >=zzmax will be yellow and anything <=zzmin will be dark blue.
If you drop the "LineStyle","none" you get contour lines even in the pure yellow area and in the pure dark blue area. I find that useful. Then you likely wish to have contour lines more densely at low z values. Then you can use:
zlevels = logspace(log10(zmin), log10(zmax), 30)
contourf(y,x,z,zlevels);
clim([zzmin zzmax]);
So you use that logspace(...) instead of linspace(zmin, zmax, 30) to have the 30 contour lines between zmin and zmax be more dense on the low z values.
You'd, of course, want the color changes match the zlevels you give (i.e., be more frequent at the lower end). Is there any way for doing this automatically?
If not, perhaps that clim seems like the closest easy option (yet often too bad).

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!