How to correctly adjust the FaceColor property of patch objects in a figure with a legend?

7 views (last 30 days)
Hello community,
I am having an issue adjusting the FaceColor property of patch objects in a figure. That is, only the legend is updated when I try to change the color of a patch object. My issue can be replicated with the code below:
% Load the figure
openfig('cylinder.fig');
The figure contains four patch objects combined to form a cylindrical shape. The figure also contains a legend.
When I save the patch objects to the variable patches I do not receive any errors:
% Get all patch objects in the figure
patches = findobj(gcf,'Type','patch');
disp(['The number of patch objects is ' num2str(length(patches)) '.'])
The number of patch objects is 4.
However, when I try to change the face color of one of the patch objects, the color is only changed inside of the legend. For example,
patches(1).FaceColor = 'r';
results in the following visual change:
My best guess is that the findobj() function is only identifying the patch objects in the legend and not the objects composing the cylinder, but I am not sure how to confirm this.
My question: Am I making a programmatic mistake? Or is there a bug in how MATLAB is applying the color change operation to the patch object? Thank you in advance for the help!
P.S. I am using MATLAB Online for my problem, in case that makes a difference.
  1 Comment
Walter Roberson
Walter Roberson on 11 Sep 2024
Weird.
The axes has 5 children; the first of those is a Rectangle. Changing the properties of the rectangle is visually reflected.
Changing the properties of the other four children (all patches) is not visually reflected -- even if you turn the patch visually off, or even if you set the XData to be all zeros.

Sign in to comment.

Accepted Answer

Voss
Voss on 11 Sep 2024
fig = openfig('cylinder.fig','visible');
There are actually 12 patches in the figure
all_patches = findall(fig,'Type','patch')
all_patches =
12x1 Patch array: Patch Patch Patch (Dark brown) Patch Patch Patch (Brown) Patch Patch Patch (Dark blue) Patch Patch Patch (Light blue)
but 8 of them have their HandleVisibility set to 'off', which is why those are not found by findobj
get(all_patches,'HandleVisibility')
ans = 12x1 cell array
{'off'} {'off'} {'on' } {'off'} {'off'} {'on' } {'off'} {'off'} {'on' } {'off'} {'off'} {'on' }
4 of the 'off' HandleVisibility patches have empty XData
get(all_patches,'XData')
ans = 12x1 cell array
{0x0 double} {4x192 double} {3x128 double} {0x0 double} {4x192 double} {3x128 double} {0x0 double} {4x192 double} {3x128 double} {0x0 double} {4x192 double} {3x128 double}
I'll copy each patch to its own axes to see where they all are
figure('Position',[10 10 300 900])
tiledlayout(4,3)
for ii = 1:12
ax = nexttile();
copyobj(all_patches(ii),ax)
set(ax,'ZDir','reverse','ZLim',[0 180])
view(ax,3)
title(ax,sprintf('patch #%d',ii))
grid(ax,'on')
end
Your syntax for setting the FaceColor is OK, once you make sure you're operating on the patch you want to be operating on.
% change two patches' FaceColor
all_patches(2).FaceColor = 'y';
all_patches(3).FaceColor = 'r';
% copy the 1st 3 again to see how the new colors have been applied
figure
tiledlayout(1,3)
for ii = 1:3
ax = nexttile();
copyobj(all_patches(ii),ax)
set(ax,'ZDir','reverse','ZLim',[0 180])
view(ax,3)
title(ax,sprintf('patch #%d',ii))
grid(ax,'on')
end
Elements 3, 6, 9, and 12 of all_patches are the ones reflected in the legend (that's why the legend updates when they change FaceColor), but they are not contained in the legend, which you can tell by deleting the legend and seeing that findall still returns the same set of patches.
figure(fig)
delete(gca().Legend)
new_all_patches = findall(fig,'Type','patch');
isequal(new_all_patches,all_patches)
ans = logical
1

More Answers (0)

Tags

Community Treasure Hunt

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

Start Hunting!