Most efficient way to distinguish handle parents in an array of handle graphics objects

7 views (last 30 days)
All, here's what I'm trying to do:
% Preallocate array of handle graphics objects, H, then add various object handles ...
H = gobjects(1,13); % Preallocate array of handle graphics objects
f1 = figure;
H(1) = subplot(2,2,1);
x = linspace(-2*pi,2*pi);
p = plot(x,cos(x),x,sin(x));
l = legend('Plot1','Plot2');
H(2) = subplot(2,2,[2,4]);
s = surf(peaks);
t = title('Yo, this is my title');
H(3) = (2,2,3);
f2 = figure;
H(4) = subplot(2,2,1);
H(5) = subplot(2,2,[2,4]);
H(6) = subplot(2,2,3);
H(7) = f1;
H(8) = f2;
H(9) = l;
H(10) = t;
H(11) = p(1);
H(12) = p(2);
H(13) = s;
As you can see, H may include all sorts of objects: figures, axes, lines, surfs, titles, legends, whatever.
So, to isolate just those objects with a 'Position' property, I do the following:
% Reduce H to eliminate both lines and single surf, then find parent objects:
H = H(isprop(H,'Position'));
H_Parents = get(H,'Parent');
Now, H and H_Parents should return something like the following:
H should give a 1x10 graphics array:
[Axes Axes Axes Axes Axes Axes Figure Figure Legend Text]
H_Parents should give a 10x1 cell array:
[Figure]
[Figure]
[Figure]
[Figure]
[Figure]
[Figure]
[Root]
[Root]
[Figure]
[Axes]
As you can see, the first "6" figures are the parents of the 6 subplots, which are just f1 and f2.
Here's my problem ... I can't seem to find an efficient way of distinguishing, for example, the parent of subplot 1 (i.e., f1) from the parent of subplot 4 (i.e, f2) from any other parent in a generalized way. My ideal solution would look something like this:
[1 1 1 2 2 2 3 3 1 4]
... because ...
... the parents of the first 3 subplots are all f1, so: [1 1 1 ...
... the parents of the next 3 subplots are all f2, so: 2 2 2 ...
... the parents of f1 and f2 are all 'root', so a third parent category is needed: 3 3 ...
... the parent of the legend, l, is f1, which is just category 1 again: 1 ...
... and the parent of the title, t, is subplot 2, which requires a 4th category, so: 4].
I hope my question is clear. My goal is to have an unambiguous identifier for each common parent amongst all of my handle graphics objects. Any help is appreciated.
Thanks in advance, Justin :)

Accepted Answer

Walter Roberson
Walter Roberson on 7 Jul 2016
ancestor(TheHandle, 'figure')
  5 Comments
jH@
jH@ on 10 Jul 2016
Thanks, again, Walter :) Let me review this response tomorrow, then I'll come back here and accept your answer. Adieu!
jH@
jH@ on 16 Jul 2016
Edited: jH@ on 16 Jul 2016
Walter, I checked out your suggestion, and it's great :) I should point out one small correction ... to get this to work, I had to start from my addendum's H_Parents_Arr (see addendum reply below) vice the H_Parents as you show. Thus, the code appears as follows:
H_Parent_Arr = [H_Parent{:}]';
[Unique_Parents,~,Parent_Idx] = unique(H_Parent_Arr)
Thanks again, worked like a charm!

Sign in to comment.

More Answers (1)

jH@
jH@ on 9 Jul 2016
I suppose my title should have been, "How to best subdivide an array of handle graphics objects into groups based on common parents," or something to this effect. Because I think I found a more ideal solution than the one I requested above.
Starting from H_Parents above:
% Convert cell array 'H_Parent' to an object array:
H_Parent_Arr = [H_Parent{:}]';
% Check equality of each object in 'H_Parent_Arr' with all other objects in 'H_Parent_Arr':
E = arrayfun(@(x) eq(x,H_Parent_Arr),H_Parent_Arr,'UniformOutput',false);
% Convert cell array 'E' to a logical array, then eliminate all non-unique rows of the logical array while preserving row order:
E = unique([E{:}],'rows','stable');
% Create cell array of original objects, grouped by common parent:
G = cell(size(E,1),1);
for ii = 1 : length(G)
G{ii} = H(E(ii,:)');
end
What do y'all think? Is there a better way to do this?
  1 Comment
jH@
jH@ on 9 Jul 2016
Incidentally, if you did want to achieve the first 'ideal' solution I requested, you could do something like this (in place of the G = cell(...) and for loop block of code above):
I = repmat((1:size(E,1))',1,size(E,2));
G_orig_ideal = I(E);

Sign in to comment.

Categories

Find more on Graphics Object Programming in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!