Why does copyobj() fail to copy over title fontsizes (and also colorbars and colormaps)?

13 views (last 30 days)
I am attempting to copy a set of subplot axes from one figure to another with copyobj. Everything seems to copy over quite nicely except for the title FontSizes, as illustrated in the example below. Does anyone know why?
h1=figure;
ax(1)=subplot(1,2,1);
plot(1:5,'rx:'); axis square
title('A','FontSize',15);
ax(2)=subplot(1,2,2);
plot(rand(1,5),'sb--'); axis square
title('B','FontSize',15);
h2=figure;
for i=1:2
copyobj(ax(i),h2);
end
  4 Comments
Matt J
Matt J on 29 Dec 2021
Edited: Matt J on 29 Dec 2021
To add a further example, colormaps and colorbars also don't copy over gracefully:
h1=figure;
for i=1:2
ax(i)=subplot(1,2,i);
imshow(rand(100));
colormap hot
colorbar
title(char('A'+(i-1)),'FontSize',20);
end
h2=figure;
for i=1:2
copyobj(ax(i),h2);
end

Sign in to comment.

Accepted Answer

Benjamin Kraus
Benjamin Kraus on 21 Jun 2022
Matt,
The issue with copyobj and the FontSize on axes is a known bug. The issue relates to there being two sources of truth: the FontSize on the axes and the FontSize on the title. When you set the FontSize on the axes, MATLAB force that change down to the Title, whether you've manually specified the FontSize on the title or not.
ax = axes;
ax.Title.String = 'Title';
ax.Title.FontSize = 30;
ax.FontSize = 15; % This resets the FontSize on the Title.
ax.Title.FontSize % This has been updated to reflect the new FontSize * TitleFontSizeMultiplier
ans = 16.5000
The issue with copyobj is the sequence in which MATLAB is (internally) copying properties from the old axes to the new axes. MATLAB copies the title's FontSize before we copy the axes FontSize, so when the axes FontSize value is copied it replaces the value copied from the old title to the new title.
Unfortunately, I don't have any good suggestions for workarounds, except to separately copy the text object (not a great workaround, but it works):
h1 = figure;
ax = axes;
title('A','FontSize',15);
h2 = figure;
ax2 = copyobj(ax,h2);
h3 = figure;
ax3 = copyobj(ax,h3);
ax3.Title = copyobj(ax.Title,ax3); % Separately copying the text object after copying the axes will preserve title properties.
  3 Comments
Benjamin Kraus
Benjamin Kraus on 1 Jul 2022
Edited: Benjamin Kraus on 1 Jul 2022
"why colorbars are figure children rather than axes children": That's a good question. I'm not sure why that design was chosen back when it was decided (it long predates my time at MathWorks), but if I had to guess it is due in large part to the fact that prior to R2014b colorbars and legends were just axes in disguise, and there was no functionality that allowed you to make an axes the parent of another axes.
I also agree that the colorbars (and legends) should be children of the axes. If there were an easy way to change that design, I would.
However, when you put an axes + colorbar into a TiledChartLayout, the colorbar is a child of the TiledChartLayout. Basically, in all scenarios currently, axes and colorbars (and legends) are siblings that share a parent, whether that parent is a figure, panel, or TiledChartLayout.

Sign in to comment.

More Answers (0)

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!