[axesm/for loop] multiple colorbars for superimposed contourfm plots keep on resetting

3 views (last 30 days)
I have some data that is of dimensions latitude, longitude, pressure level (height). I plot them superimposed in an axesm axis with contoufm plots, using a for loop on pressure levels.
Due to the fact that values between pressure levels are greatly different, I choose to make each level with its own clim and plot a colorbar for each level. My problem is that after the first colorbar is drawn and the second shows up, the limits of the first colobar are updated to those of the second, and the second and first are reset to the values of the third and so on. (see image)
How can I lock each colorbar?
levelNames = { '200' ; '500' ; '850'} ;
nLevels = size( levelNames , 1 );
lons = -100:0.25:60 ;
lats = 75:-0.25:30 ;
lonLim = [lons(1) , lons(end)] ;
latLim = [lats(1) , lats(end)] ;
levels = [ 200 500 850 ];
[ lonGrid , latGrid ] = meshgrid(lons , lats );
iTime = 1;
figure(1)
axesm ('gstereo','MapLatLimit',fliplr(latLim),'MapLonLimit',lonLim,'ParallelLabel','on','MeridianLabel','on','Grid','on','MLabelParallel','south','PLabelMeridian','east');
coast = load('coastlines');
plot3m(coast.coastlat, coast.coastlon, zeros(size(coast.coastlon)), 'k', 'LineWidth', 1);
zLevel = ( normalize(levels,'range') ) ;
zLevel = fliplr(zLevel);
[ nLats , nLons , nTime ] = size(t) ;
leftPos = 0;
for iLevel = 1:nLevels
%s3 is the input data of dimensions longitude,latitude,level,time
%I have to permute it so that tmpData is latitude,longitude,time,level
%I also have to flipup the latitudes because they are put in increasing
%order in s3
tmpData = flipud(permute(s3(:,:,:,iLevel), [ 2 1 3 4 ]));
minTmpData{iLevel} = min(tmpData(:));
maxTmpData{iLevel} = max(tmpData(:));
zValue = zLevel(iLevel);
tmpdata1 = tmpData(:,:,iTime) ;
h = hgtransform() ;
h.Matrix = makehgtform('translate', [0 0 zValue]) ;
tmpdata2 = tmpdata1;
percentilesTmpData = prctile(tmpData,[5 95], 'all');
tmpdata2((tmpdata2>=percentilesTmpData(1)) & (tmpdata2<=percentilesTmpData(2))) = NaN ;
[ C , H ] = contourfm(latGrid,lonGrid,tmpdata2, 'parent', h , 'LineWidth',2);
caxis([minTmpData{iLevel} maxTmpData{iLevel}]);
caxis(gca, 'manual');
cb{iLevel} = contourcbar ;
cb{iLevel}.Limits = [minTmpData{iLevel} maxTmpData{iLevel}];
leftPos = leftPos + 0.1;
set(cb{iLevel},'Position',[leftPos 0.1 0.025 0.1])
cb{iLevel}.Label.String = [ num2str(levelNames{iLevel}) 'hPa' ] ;
hold on
end
drawnow
tightmap
view(20,35)
hold off
ax = gca;
zticks(ax, fliplr(zLevel) )
zticklabels(ax,flip(levelNames));

Accepted Answer

Ruchika Parag
Ruchika Parag on 25 Nov 2024
Edited: Ruchika Parag on 25 Nov 2024
Hi @manuel FOSSA, to resolve this, you can use a separate axes for each colorbar, ensuring that each colorbar remains independent. Here is how you can modify your code:
levelNames = {'200', '500', '850'};
nLevels = numel(levelNames);
levels = [200, 500, 850];
lons = -100:0.25:60;
lats = 75:-0.25:30;
lonLim = [lons(1), lons(end)];
latLim = [lats(1), lats(end)];
[lonGrid, latGrid] = meshgrid(lons, lats);
nTime = 1;
s3 = randn(numel(lons), numel(lats), nLevels, nTime);
figure(1)
axesm('gstereo', 'MapLatLimit', fliplr(latLim), 'MapLonLimit', lonLim, ...
'ParallelLabel', 'on', 'MeridianLabel', 'on', 'Grid', 'on', ...
'MLabelParallel', 'south', 'PLabelMeridian', 'east');
coast = load('coastlines');
plot3m(coast.coastlat, coast.coastlon, zeros(size(coast.coastlon)), 'k', 'LineWidth', 1);
zLevel = normalize(levels, 'range');
zLevel = fliplr(zLevel);
leftPos = 0;
for iLevel = 1:nLevels
tmpData = flipud(permute(s3(:, :, iLevel, :), [2, 1, 3, 4]));
minTmpData = min(tmpData(:));
maxTmpData = max(tmpData(:));
zValue = zLevel(iLevel);
tmpdata1 = tmpData(:, :, 1);
h = hgtransform();
h.Matrix = makehgtform('translate', [0, 0, zValue]);
percentilesTmpData = prctile(tmpData, [5, 95], 'all');
tmpdata2 = tmpdata1;
tmpdata2((tmpdata2 >= percentilesTmpData(1)) & (tmpdata2 <= percentilesTmpData(2))) = NaN;
[C, H] = contourfm(latGrid, lonGrid, tmpdata2, 'parent', h, 'LineWidth', 2);
caxis([minTmpData, maxTmpData]);
cbAxes = axes('Position', [leftPos, 0.1, 0.025, 0.1], 'Visible', 'off');
cb{iLevel} = colorbar(cbAxes, 'Limits', [minTmpData, maxTmpData]);
cb{iLevel}.Label.String = [levelNames{iLevel}, ' hPa'];
leftPos = leftPos + 0.1;
hold on
end
drawnow
tightmap
view(20, 35)
hold off
ax = gca;
zticks(ax, fliplr(zLevel));
zticklabels(ax, flip(levelNames));
This approach should ensure that each colorbar maintains its own limits and does not affect the others. Hope this helps!

More Answers (0)

Categories

Find more on Colormaps in Help Center and File Exchange

Products


Release

R2024b

Community Treasure Hunt

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

Start Hunting!