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

61 visualizaciones (últimos 30 días)
Sim
Sim el 17 de Jun. de 2024
Editada: Sim el 17 de Jun. de 2024
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 comentarios
Ganesh
Ganesh el 17 de Jun. de 2024
Could you please share the entire code you are using?
Sim
Sim el 17 de Jun. de 2024
Editada: Sim el 17 de Jun. de 2024
Thanks for the comment @Ganesh, code added :-)
The code I added here is similar to that one I posted in another question and answer.

Iniciar sesión para comentar.

Respuesta aceptada

Steven Lord
Steven Lord el 17 de Jun. de 2024
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 comentario
Sim
Sim el 17 de Jun. de 2024
Editada: Sim el 17 de Jun. de 2024
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

Iniciar sesión para comentar.

Más respuestas (1)

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

Categorías

Más información sobre Dialog Boxes en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by