[axesm/for loop] multiple colorbars for superimposed contourfm plots keep on resetting
3 views (last 30 days)
Show older comments
manuel FOSSA
on 12 Nov 2024
Commented: manuel FOSSA
on 25 Nov 2024
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));
0 Comments
Accepted Answer
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)
See Also
Categories
Find more on Colormaps in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!