Colorbar doesn't match with contourf plot
Ältere Kommentare anzeigen
As you see colors do not match with values. Is there anything I missed here?
figure
contourf(diff)
colormap('jet');
set(gca,'visible','off')
colorbar
caxis([0 100])
4 Kommentare
Adam Danz
am 17 Jan. 2021
That's fishy. Could you attach a mat file with the diff values?
Rakuen
am 17 Jan. 2021
I'm not sure what you're expecting to see from a contour of these data. As you can see in the surface plot below, the data are mostly flat.
load('matlab.mat')
surf(diff)
Rakuen
am 18 Jan. 2021
Antworten (2)
Robert Lobbia
am 18 Jul. 2022
2 Stimmen
I had this issue as well and discovered that I needed to include number of levels directly in the countourf call:
WORKS: contourf(x,y,ZZ,256)
DOES NOT WORK: contourf(x,y,ZZ)
the number of levels (256 above) needs to be close to dynamic range of data as CData mapping/binning occurs when contourf is called (can't change it later through any caxis/clim/colormap/colorbar settings). I only had this issue with datasets where the values of my matrix where orders of magnitude apart, which makes sense since the CData map matlab linearly created from the data just included the highest level as one color and most other values as the other color limit.
2 Kommentare
Hi!
Something similar happened to me.
I have made a contourf interpolating results with meshgrid and it plots a graph which does not correspond to the values that I put as input with the colors of the colorbar (There are points where it should be yellow or red and it is blue, or other points which have markedly different values and are the same color). I don't know if it's a problem with the interpolation method, I think not since I've checked that and the numbers are consistent. I don't see a problem with the contour either. I don't know if I should use another interpolation method and I dont unterstand what exactly is wrong


clear all;clc;
A=[77.3139227401096,77.3120257063849,77.3120257063849,77.3120257063849,77.3120257063849,77.3120257063849,77.3120257063849,77.3120257063849,77.3120257063849,77.8499350764564,77.8442382759329,77.8400158037560,77.8367460305253,77.8341382601430,77.3189088790396,77.3120257063849,77.3120257063849,77.3120257063849,77.3120257063849,77.4228460196533,77.3770975908979,77.3678714954335,77.3624256179988,77.3588314539844,77.3562741687948,77.3543880471537,77.3529118848689,77.3517359358068,77.8230143346564,77.5947167588728,77.4572289300964,77.3536200322737,77.2815354478640,77.1958950775090,77.1462000726089,77.1176650859710,77.1045877194747,77.0939198939992,77.0960045406636,77.0936701640036,77.0918470331206,77.0903910018129,78.9250781251261,78.2607772080247,77.8571819100295,77.5445345646900,77.1777675777582,77.1067936547286,77.0560757369439,77.0204796252278,77.0021470133600,76.9934357792392,76.9874018876342,76.9841903129164,76.9834146935698,76.9832804850934];
torque=[-40,-30,-20,-10,10,20,30,40,50,60,70,80,90,100,-40,-30,-20,-10,10,20,30,40,50,60,70,80,90,100,-40,-30,-20,-10,10,20,30,40,50,60,70,80,90,100,-40,-30,-20,-10,10,20,30,40,50,60,70,80,90,100];
rpmrange=[6,6,6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,8,8,8,8,8,8,8,8,8,8,8,10,10,10,10,10,10,10,10,10,10,10,10,10,10,12.5,12.5,12.5,12.5,12.5,12.5,12.5,12.5,12.5,12.5,12.5,12.5,12.5,12.5];
[xmesh,ymesh]=meshgrid(torque,rpmrange);
vq=griddata(torque,rpmrange,A,xmesh,ymesh);
contourf(xmesh,ymesh,vq,1000,'EdgeColor','none')
xlabel('Torque increase [%]');
ylabel('RPM range [*10^3]');
title('Torque Sensivity Study');
hc = colorbar;
set(get(hc,'title'),'string','LapTime [s]')
colormap(flipud(jet))
Star Strider
am 14 Aug. 2022
Actually, it is not necessary to interpolate it, and the interpolation used in the posted code is incorrect. See my Answer to your previous post Contour Plot Wrong Colors.
Cris LaPierre
am 18 Jan. 2021
Bearbeitet: Cris LaPierre
am 18 Jan. 2021
I believe the issue is that this data set doesn't lend itself well to a contour plot. 98.6% of the data is <10 or NaN. Your lowest contour is set to the min value but that is a single point in the 256x256 array. The default contour levels are in steps of 5000 for your data (range of 0.00006-3.5e4). Everything below the min value is set to white, and everything between min and 5000 should be set to the min color. However there are not levels to speak of. Just individual points.
If you want to recreate the issue, see this simplified example.
figure
% most values are near zero. No structure, so no clear contour boundaries
Z=rand(25);
% Create one point that is much larger
Z(5,5)=35000;
contourf(Z);
colorbar
colormap('jet');
caxis([0 100])
I can't explain how it's picking the color it picks (it appears to be the color in the middle of the colormap), but the issue is related to your levels. Try setting the levels you want as an input using this syntax:
S=load('matlab.mat');
figure
contourf(S.diff,[0:10:100]);
colormap('jet');
set(gca,'visible','off')
colorbar
caxis([0 100])
8 Kommentare
Rakuen
am 18 Jan. 2021
Cris LaPierre
am 18 Jan. 2021
I don't fully get it either, but it seems part of the problem is that the upperlimit of the caxis is << the second contour level. Adding levels that are within your caxis limits might gives it something to anchor to. Just my thoughts, though.
> I still don't understand why it works with defining levels but doesn't work without it
I think there's some confusion between setting contour levels and setting the color limits. When caxis is used to set the color scale, that does not affect the contour levels. It will only change the range of colors displayed in the already-established contour ridges.
The vast majority of values in the diff matrix are less than 100 (see histogram below) yet the max value is 36757. When levels are not specified in contour() they are chosen automatically to linearly cover the range of values in "diff".
That results in the following default contour levels (r2020b)
[~, cobj] = contourf(diff);
cobj.LevelList --> [6.097e-05 5000 10000 15000 20000 25000 30000 35000]
When you change the color range, the list levels do not change. The small, relevant values that are below 5000 still do not appear as separate levels.
When you specify list levels, that's a different story. Now you're telling contourf() to only pay attention to a limited range of values in your input matrix and the result is more useful contour levels that vary within the same range as the critical section of your data.
[~, cobj] = contourf(diff,0:10:100);
cobj.LevelList --> [0 10 20 30 40 50 60 70 80 90 100]
% Show distribution of "diff" values
S=load('matlab.mat');
figure()
edges = [0,exp(linspace(log(.1),log(max(S.diff(:))),50))];
histogram(S.diff(:), edges)
set(gca,'YScale','log','XScale','log')
axis tight
xlabel('"diff" values')
ylabel('Count')
title('Distribution of "diff" values')
> I still don't understand why ... it picks that single color.
Neither do I. The base color in the original contour plot takes a value around 50 on the colorbar and that makes no sense to me. You can use caxis to zoom in around 50 to confirm this. 50 is far from the median or mean input value for the first bin [6.097e-05, 5000].
S=load('matlab.mat');
figure()
contourf(S.diff)
caxis([40,60])
colormap('jet')
colorbar()
Keep in mind this green-ish level acts as a base and isn't defined in the 2xn output of contourf(). For example, the majenta "x" below are the only coordinates represented in the output matrix (uses getContourLineCoordinates from the file exchange).
S=load('matlab.mat');
figure()
cmat = contourf(S.diff)
colormap('jet')
colorbar()
T = getContourLineCoordinates(cmat); % see file exchange
hold on
plot(T.X, T.Y, 'mx', 'MarkerSize', 3)

Zoomed into section around x=65 y=155

Rakuen
am 18 Jan. 2021
> ... it limits and resplits the range of values according to that scale
To be more precise, it changes the range of color values while maintainging the level values. The two plots below show the exact same data with the exact same contour levels. The only difference is the the plot on the right defines the range of colors from [-2, 2] instead of the full [-6.36, 7.56] range.
As explained in the documentation, all values greater than or less than the caxis range will have the same color as the bounds.
The key point is the contourf creates the levels and caxis determines what range of colors to use.
In your case, the critical values were all being squished into the same bin and were assigned the same level. Colors cannot vary within a level no matter what color range you use. The only way to add resolution is to define finer levels.
rng('default') % for reproducibility
data = peaks(20);
figure()
subplot(1,2,1)
[~, cobj1] = contourf(data);
axis equal; colorbar()
title('Full color range')
subplot(1,2,2)
[~, cobj2] = contourf(data);
axis equal; colorbar()
title('Limited color range')
% Rescale color
caxis([-2 2])
% Show levels of each contour
cobj1.LevelList
cobj2.LevelList
If that's still not clear, here's an analogy. Let's say contour is used to segment elevations of a mountain range into 10 elevation bins. The first bin contains anything from -10 to -5 meters from sea level. This is the deep blue level below. Everything within that range of elevation will be the same color no matter what caxis range you specify because that is one bin. If you want to see differences between -10 and -5 meters the only way to do that is to change the bins (levels). If you set the caxis range to [-10,-5] and the first level is defined by [-10,-5] you'll see only two colors: one for values [-10:-5] (blue level below, right) and one for values greater than -5 (red levels below, right).
rng('default') % for reproducibility
data = peaks(20)*3+10;
figure()
subplot(1,2,1)
[~, cobj1] = contourf(data);
axis equal; colorbar(); colormap('jet')
title('Full color range')
subplot(1,2,2)
[~, cobj2] = contourf(data); colormap('jet')
axis equal; colorbar()
title('Limited color range to first level')
% Rescale color
caxis(cobj2.LevelList(1:2))
Changing caxis does not affect the contour levels. It "recolors" the plot, but uses the same contour levels as the original image.
data = rand(10);
contourf(data)
colormap('jet');
set(gca,'visible','off')
colorbar
figure
contourf(data)
colormap('jet');
set(gca,'visible','off')
colorbar
caxis([0 0.5])
Rakuen
am 19 Jan. 2021
Naseef Muhammed
am 1 Nov. 2023
setting "colormap('jet100')" will create the figure like what you want. That is, Number of levels, caxis and colormap value (here, jet100) must be same!
Kategorien
Mehr zu Contour Plots finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!











