I have several contour plots on a cylinder that I made in MatLab. In some of them the black text from the colorbar is obstructed by dark colors in the plot. In others, the color of the text is fine so I would rather not change the color of the text. Is there an easy way in MatLab to put a rectangular patch (either white or gray) neatly around the colorbar and the surrounding text but behind it so that only a small amount of the contour is hidden?
I've given a link to 4 .fig files on google drive (they're too big to attach), and a .png of one of them where I put a white block around the colorbar (I would like it to be filled and behind the colorbar but in front of the contour) to show what I am hoping to get.

6 Comments

Why not just set the colorbar location or position so that it's adjacent to the axis?
That would be a lot simpler than what you're requesting.
The problem is twofold. The colorbar is itself an axis and its position is relative to the figure, not relative to the data in your main axes. So you'd have to set a rectangle on your axes in your data-units and then you'd have to position the colorbar axes on top of that rectangle by converting its units to your data units. Of course that's posible but it requires a bunch of other modifications such as setting the axis limits on your main axis and considering figure-resizing. There are other white background objects that also use the same figure coordinates as the colorbar such as adding an additional axis or using an annotation text box. But the 2nd problem is that the colorbar cannot be placed over an annotation box nor upon another axes. So the solution isn't clearcut.
Nathaniel H Werner
Nathaniel H Werner on 15 Oct 2019
Edited: Nathaniel H Werner on 15 Oct 2019
Were you able to look at the figures I uploaded onto Google Drive? The figures are plotted are on cylindrical slices, and I have the camera view angle positioned to focus on the portion of my flow of interest. As far as I am concerned, moving the color bar is not a valid option because I would have to adjust the settings of my camera in Matlab. If I can take the part of my image but remove the color bar and save it as another figure, and then add the color bar back in but to the right in "empty space" that might also work.
The zip file is crazy large (and as with all downloaded zips, poses a security risk although that typically isn't a problem in this forum). A simple screenshot would be much easier to view and can be hosted here in the forum.
The view angle doesn't affect the colorbar position within the figure so I'm puzzled.
Nathaniel H Werner
Nathaniel H Werner on 15 Oct 2019
Edited: Nathaniel H Werner on 15 Oct 2019
This is exactly why I uploaded the figures, because a screenshot doesn't show all the relevant information.
In all the figures the data is on a cylindrical slice and the camera view angle and target are set to focus on the area of interest and no more. If you open a single figure file, and rotate it about the vertical axis you will see this. Likewise, zooming in or out just expands the field of view but the colorbar doesn't change size or position.
If you're worried about security (no one has ever raised this concern to me before), I can upload a screenshot of the rotated image myself. I thought having the .fig files would be more useful.
I see what you mean now (I saw your figs).
I think your best bet is to add another axis that's slightly bigger than your colorbar (you can get the size and position of the colorbar from its handle). The axis can be set to be on the edge of your figure. But you can't place the colorbar of one axis on another axis so your "fake" axis will have to have the same colormap and color-range as your original data. Then you assign the colorbar to your new, fake axis. Does that make sense?
I think I understand the concept but I'm not sure how to do that.

Sign in to comment.

 Accepted Answer

Adam Danz
Adam Danz on 16 Oct 2019
Edited: Adam Danz on 18 Oct 2019
I still think repositioning the axis to make room for a marginal colorbar is the cleanest and most efficient approach (see the various position properties of axes).
However, here's how to add an axes under a cloned colorbar. The basic idea is to create a new axis on top of the existing colorbar, set the axis colormap properties to match the main axis, then add a new colorbar to the new axes. Then set the colorbar properties to match those of the initial colorbar. Toward the end of the code below, you can set the transparency level of the new axis. Note that the original colorbar is turned off but still exists. See inline comments for more detail.
% Open one of your figures
% Get fig, axes, and colorbar handles from current figure
% Assumes 1 axes and 1 colorbar per figure
fh = gcf();
axh = findall(fh, 'Type','Axes');
cbh = findall(fh, 'Type','ColorBar');
% Create an axis on top of the current colbar
ax2 = axes('position',cbh.Position,'XTick',[],'YTick',[],'Box','on');
% expand the size of the new axis
% The axis will be 4X wider and its height will be slight larger to make room for title
ax2.Position(1) = ax2.Position(1) - .01;
ax2.Position(2) = ax2.Position(2) - .01;
ax2.Position(3) = ax2.Position(3)*4;
ax2.Position(4) = 1 - ax2.Position(2) - .01;
% The new axis must match the color scale of the one we're imitating
ax2.Colormap = axh.Colormap;
ax2.ColorScale = axh.ColorScale;
% set colorbar in new axes (you can add other important properties as needed)
cb2 = colorbar(ax2);
cb2.Position = cbh.Position;
cb2.FontSize = cbh.FontSize;
cb2.Limits = cbh.Limits;
cb2.LimitsMode = cbh.LimitsMode;
cb2.TickDirection = cbh.TickDirection;
cb2.YAxisLocation = cbh.YAxisLocation;
caxis(ax2,cbh.Limits)
% Set title of colorbar
th = title(cb2,cbh.Title.String,'Units','Normalize');
th.Position(1) = th.Position(1) - min(0,th.Extent(1)-.00); %Move title to fit on axes
% set transparency of new axes (undocumented)
% v---transparency (0:1)
ax2.Color = [1 1 1 .6];
% Turn off old colorbar (keep it around in case you need to reference it later)
cbh.Visible = 'off';

6 Comments

It may also help to increase the font size on the colorbar and/or to make the font bold.
cb2.FontWeight = 'bold';
cb2.FontSize = 12;
Thank you, this is exactly what I am looking for. I tried adjusting the weight and fontsize of the text and I was getting inconsistent results, so I like this way better. Even if it is not the most efficient.
I have a need to slightly adjust the range of the colorbar and contour after I save the figure. For the figure in your answer if I type this into the command window will it adjust both axes together or will I have to do both separately?
caxis([-6 6])
Good question. The new colorbar is completely unrelated to your main axes. So any changes to your color range or colormap in the main axes needs to be made in the new axes/colorbar. Better yet, just add the new colorbar after you've made any changes to your main axes, if possible.
The first input to caxis() is the axis handle where you can specify which axes will be affected.
caxis(h,[lower,upper])
If you plan to interactively make lots of changes to the colormap or color range after the production of the 2nd colorbar, you could set up a listener to adjust the new colorbar every time the main axes are adjusted. That adds another level of complexity.
Nathaniel H Werner
Nathaniel H Werner on 16 Oct 2019
Edited: Nathaniel H Werner on 16 Oct 2019
I see. I'm just post-processing these figures for a conference in a few weeks, and the range of the colorbar for each figure is different for each different variable (, and ). I think it would just be easiest to adjust it after the figure is saved.
Sure, just apply caxis() to both sets of axes.
It would be a good idea to spot-check this by comparing the new/old colorbars within a figure to make sure they match. I see no reason why they wouldn't match and they certainly matched for all 4 figures you provided in the zip file. But it's always reassuring to keep checking.
You can use the last line of my answer to toggle 'on' or 'off' the original colorbar.
If you wanted to be extra vigilant, you could add a line or two of code that detects differences in the y-tick-labels of each colorbar or the colormap of each axis since you have access to both sets of handles. Practicing these types of "santify checks" will let you sleep better at night.
Example:
test = isequal(cb2.YTickLabel, cbh.YTickLabel) & isequal(cb2.YLim, cbh.YLim) & isequal(axh.Colormap, ax2.Colormap);
if ~test
error('Property mismatch between pseudo-colorbar and main axes.')
end

Sign in to comment.

More Answers (0)

Products

Release

R2018b

Community Treasure Hunt

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

Start Hunting!