필터 지우기
필터 지우기

Error: Children may only be set to a permutation of itself

조회 수: 54 (최근 30일)
Sim
Sim 2024년 6월 17일
편집: Sim 2024년 6월 17일
When I use the following commands in a subplot environment
getChildren = get(gca,'Children');
set(gca,'Children',[getChildren(4:5); getChildren(1:3)]) % I use this command to reshuffle the several objects in my plot (similarly to uistak)
Things work in the first subplot, i.e. suplot(1,2,1). But, when Matlab goes to the second subplot, i.e. subplot(1,2,2), it is not able to produce my graphics and gives me the following error:
Error using matlab.graphics.axis.Axes/set
Children may only be set to a permutation of itself.
Error in MyFile (line 215)
set(gca,'Children',[getChildren(4:5); getChildren(1:3)])
Do you have any suggestion to avoid/solve this error?
Here following a simplified code:
% Graph
s = [1 1 1 3 3 6 7 8 9 10 4 12 13 5 15 16 17 18 19 19 20 20 17 24 25 4 27 28 29];
t = [2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30];
G = graph(s,t);
% Node ID: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
G.Nodes.X = [2 1 3 2 4 4 5 4 5 4 5 1 3 3 5 6 7 6 8 7 9 8 9 8 9 10 1 1 0 1]';
G.Nodes.Y = [2 1 3 9 3 5 8 12 13 18 21 15 18 21 0 2 8 12 15 20 10 22 18 5 4 4 5 8 12 23]';
% Subgraphs
Gpath{1} = subgraph(G,shortestpath(G,4,14));
Gpath{2} = subgraph(G,shortestpath(G,4,26));
Gpath{3} = subgraph(G,shortestpath(G,4,30));
Gpath{4} = subgraph(G,shortestpath(G,3,10));
Gpath{5} = subgraph(G,shortestpath(G,3,28));
Gpath{6} = subgraph(G,shortestpath(G,3,21));
Gpath{7} = subgraph(G,shortestpath(G,17,12));
Gpath{8} = subgraph(G,shortestpath(G,17,23));
Gpath{9} = subgraph(G,shortestpath(G,17,26));
% Figure
for k = 1 : 2
subplot(3,2,k);
hold on
p(1) = plot(G,'XData',G.Nodes.X,'YData',G.Nodes.Y,'LineWidth',1,'EdgeColor','k','NodeColor','k');
for i = [1 2 3]
p(2) = plot(Gpath{i},'XData',Gpath{i}.Nodes.X,'YData',Gpath{i}.Nodes.Y,'EdgeColor','y','NodeColor','y');
p(2).NodeLabel = {};
p(2).EdgeAlpha = 1;
p(2).LineWidth = 5;
% p(2).DisplayName = 'Banana';
end
for i = [7 8 9]
p(3) = plot(Gpath{i},'XData',Gpath{i}.Nodes.X,'YData',Gpath{i}.Nodes.Y,'EdgeColor','g','NodeColor','g');
p(3).NodeLabel = {};
p(3).EdgeAlpha = 1;
p(3).LineWidth = 9;
p(3).DisplayName = 'Apple';
end
for i = [4 5 6]
p(4) = plot(Gpath{i},'XData',Gpath{i}.Nodes.X,'YData',Gpath{i}.Nodes.Y,'EdgeColor','r','NodeColor','r');
p(4).NodeLabel = {};
p(4).EdgeAlpha = 1;
p(4).LineWidth = 15;
p(4).DisplayName = 'Strawberry';
end
text(8,.2,'hello')
plot([0.5 0.6],[0 6],'color',[0.6 0.6 0.6],'LineWidth',5);
rectangle('Position',[7,1,2,0.5],'FaceColor',[0.4 0.4 0.4]);
a = get(gca,'Children');
b = findobj('Type','GraphPlot');
idx1 = find(~cellfun(@isempty,{b.DisplayName})); % GraphPlots with name
idx2 = find(cellfun(@isempty,{b.DisplayName})); % GraphPlots without name
c = vertcat(flipud(b(idx2)),flipud(b(idx1)));
set(gca,'Children',[c; setdiff(a,b)])
legend(c)
end
Error using matlab.graphics.axis.Axes/set
Children may only be set to a permutation of itself.
% The error that I get in my machine with the above mentioned code:
Error using matlab.graphics.axis.Axes/set
Children may only be set to a permutation of itself.
Error in uistack_graph_subgraph_2 (line 61)
set(gca,'Children',[c; setdiff(a,b)])
  댓글 수: 2
Ganesh
Ganesh 2024년 6월 17일
Could you please share the entire code you are using?
Sim
Sim 2024년 6월 17일
편집: Sim 2024년 6월 17일
Thanks for the comment @Ganesh, code added :-)
The code I added here is similar to that one I posted in another question and answer.

댓글을 달려면 로그인하십시오.

채택된 답변

Steven Lord
Steven Lord 2024년 6월 17일
In programmatic code, ideally you should use a specific axes handle rather than trusting that gca returns the axes you think it does. [If your user were to click on a different axes to select it, for example, that would make it the current axes even if you last plotted in a different one.] In your example, either call subplot with an output argument (so it returns the handle of the axes) or use the ancestor function on one of the graphics objects in the axes to get the axes that contains it.
f = figure;
ax = axes; % output argument approach
h = plot(ax, 1:10, 1:10);
ax2 = ancestor(h, 'axes'); % ancestor approach
isequal(ax, ax2) % Both refer to the same axes
ans = logical
1
f2 = ancestor(h, 'figure');
isequal(f, f2) % same figure too
ans = logical
1
  댓글 수: 1
Sim
Sim 2024년 6월 17일
편집: Sim 2024년 6월 17일
Thanks a lot!
In case I use subplot, and if I understood correctly, I then need to call subplot with an output argument, and add that output argument (i.e. the handle of the axes) everywhere I plot something, where I get/set "Children", and where I call findobj and legend, right?
In my secific case, I would need to use the output argument (i.e. the handle of the axes) in the following parts of code:
(1) ax = subplot(3,2,k); % <-- call subplot with an output argument (so it returns the handle of the axes)
(2) p(1) = plot(ax,G,...
p(2) = plot(ax,Gpath{i},...
p(3) = plot(ax,Gpath{i},...
p(4) = plot(ax,Gpath{i},...
text(ax,...
plot(ax,...
rectangle(ax,...
(4) a = get(ax,'Children');
(5) b = findobj(ax,'Type','GraphPlot');
(6) set(ax,'Children',[c; setdiff(a,b)])
(7) legend(ax,c)
The entire code would then read and run as follows:
clear all; clc; close all;
% Graph
s = [1 1 1 3 3 6 7 8 9 10 4 12 13 5 15 16 17 18 19 19 20 20 17 24 25 4 27 28 29];
t = [2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30];
G = graph(s,t);
% Node ID: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
G.Nodes.X = [2 1 3 2 4 4 5 4 5 4 5 1 3 3 5 6 7 6 8 7 9 8 9 8 9 10 1 1 0 1]';
G.Nodes.Y = [2 1 3 9 3 5 8 12 13 18 21 15 18 21 0 2 8 12 15 20 10 22 18 5 4 4 5 8 12 23]';
% Subgraphs
Gpath{1} = subgraph(G,shortestpath(G,4,14));
Gpath{2} = subgraph(G,shortestpath(G,4,26));
Gpath{3} = subgraph(G,shortestpath(G,4,30));
Gpath{4} = subgraph(G,shortestpath(G,3,10));
Gpath{5} = subgraph(G,shortestpath(G,3,28));
Gpath{6} = subgraph(G,shortestpath(G,3,21));
Gpath{7} = subgraph(G,shortestpath(G,17,12));
Gpath{8} = subgraph(G,shortestpath(G,17,23));
Gpath{9} = subgraph(G,shortestpath(G,17,26));
% Figure
for k = 1 : 2
ax = subplot(3,2,k);
hold on
p(1) = plot(ax,G,'XData',G.Nodes.X,'YData',G.Nodes.Y,'LineWidth',1,'EdgeColor','k','NodeColor','k');
for i = [1 2 3]
p(2) = plot(ax,Gpath{i},'XData',Gpath{i}.Nodes.X,'YData',Gpath{i}.Nodes.Y,'EdgeColor','y','NodeColor','y');
p(2).NodeLabel = {};
p(2).EdgeAlpha = 1;
p(2).LineWidth = 5;
% p(2).DisplayName = 'Banana';
end
for i = [7 8 9]
p(3) = plot(ax,Gpath{i},'XData',Gpath{i}.Nodes.X,'YData',Gpath{i}.Nodes.Y,'EdgeColor','g','NodeColor','g');
p(3).NodeLabel = {};
p(3).EdgeAlpha = 1;
p(3).LineWidth = 9;
p(3).DisplayName = 'Apple';
end
for i = [4 5 6]
p(4) = plot(ax,Gpath{i},'XData',Gpath{i}.Nodes.X,'YData',Gpath{i}.Nodes.Y,'EdgeColor','r','NodeColor','r');
p(4).NodeLabel = {};
p(4).EdgeAlpha = 1;
p(4).LineWidth = 15;
p(4).DisplayName = 'Strawberry';
end
text(ax,8,.2,'hello')
plot(ax,[0.5 0.6],[0 6],'color',[0.6 0.6 0.6],'LineWidth',5);
rectangle(ax,'Position',[7,1,2,0.5],'FaceColor',[0.4 0.4 0.4]);
a = get(ax,'Children');
b = findobj(ax,'Type','GraphPlot');
idx1 = find(~cellfun(@isempty,{b.DisplayName})); % GraphPlots with name
idx2 = find(cellfun(@isempty,{b.DisplayName})); % GraphPlots without name
c = vertcat(flipud(b(idx2)),flipud(b(idx1)));
set(ax,'Children',[c; setdiff(a,b)])
legend(ax,c)
end

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Sim
Sim 2024년 6월 17일
Solved just by adding "gca", as first argument of findobj, i.e. by using:
b = findobj(gca,'Type','GraphPlot');

Community Treasure Hunt

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

Start Hunting!

Translated by