将嵌套单元绘制为预定义结构:MATLAB
Plotting a nested cell as a predefined structure: MATLAB
我有一系列代表树结构的嵌套单元格。这些单元格之一及其相应结构的示例如下图所示:
我想知道在Matlab中绘制相应结构的可能方法有哪些。到目前为止,我发现 this method here 这可能是可用的最佳解决方案,但我仍在努力实现它。谢谢
这样就不会没有答案了...
myCellArray = {0,0,{1,0,0,{1,0},0,0},{1,0,{1,0},0},{1,1},0,0};
[myTreeArray,myTreeEvals] = getTreeArray(myCellArray);
MYtreeplot(myTreeArray,myTreeEvals)
对于第四个示例输出,您可以根据需要进行修改:
两个函数,稍微改编自 SO 答案,如下所示。
首先基于@Wolfie 的:
function [treearray, nodevals] = getTreeArray(cellarray)
% initialise the array construction from node 0
[nodes, ~, nodevals] = treebuilder(cellarray, 1,0);
nodevals = decellify(nodevals);
treearray = nodes-1;
% recursive tree building function, pass it a cell array and root node
function [out, node, nodevals] = treebuilder(cellarray, rnode,skipFirst)
% Set up variables to be populated whilst looping
out = []; nodevals = [];
% Start node off at root node
node = rnode;
% Loop over cell array elements, either recurse or add node
num2Loop = 1:numel(cellarray);
% ADDED, with input to function everywhere used
if skipFirst
num2Loop = 2:numel(cellarray);
end
%End ADDED
for ii = num2Loop
tb = []; node = node + 1;
if iscell(cellarray{ii})
[tb, node] = treebuilder(cellarray{ii}, node,1);
end
out = [out, rnode, tb];
end
nodevals = [nodevals,cellarray];
end
function data = decellify(data)
try
data = cellfun(@decellify,data,'un',0);
if any(cellfun(@iscell,data))
data = [data{:}];
end
catch
% a non-cell node, so simply return node data as-is
end
end
end
并基于此SO answer for treeplots:
function MYtreeplot(treearray,nodevals)
% At first we need to get the get the x and y coordinates of every node in the original tree plot and find all leaves in it
[x,y] = treelayout(treearray);
leaves = find( y == min(y) );
%ADDED
if nargin < 2
leaveParents = find( y ~= min(y) );
leaveChilds = leaves;
else
leaveParents = find([nodevals{:}]==1);
leaveChilds = find([nodevals{:}]~=1);
end
%END ADDED
num_layers = 1/min(y)-1;
chains = zeros(num_layers, length(leaves));
% Next, we reconstruct every chain in the tree plot and store it in a matrix (by doing so, we can later change the y position of the nodes)
for l=1:length(leaves)
index = leaves(l);
chain = [];
chain(1) = index;
parent_index = treearray(index);
j = 2;
while (parent_index ~= 0)
chain(j) = parent_index;
parent_index = treearray(parent_index);
j = j+1;
end
chains(:,l) = padarray(flip(chain), [0, num_layers-length(chain)], 'post');
end
% Now we compute the new y-coordinates determined by the row index in the matrix and dependent on the number of layers in the tree:
y_new = zeros(size(y));
for i=1:length(treearray)
[r,c] = find(chains==i, 1);
y_new(i) = max(y) - (r-1)*1/(num_layers+1);
end
% We can now plot the re-positioned nodes and add the connecting lines:
figure;plot(x(leaveParents), y_new(leaveParents), '.r','MarkerSize',16);
hold on
plot(x(leaveChilds), y_new(leaveChilds), '.k','MarkerSize',16);
for c=1:size(chains, 2)
line_x = x(chains(chains(:,c)>0, c));
line_y = y_new(chains(chains(:,c)>0, c));
line(line_x, line_y);
end
axis([0 1 0 1]);
我有一系列代表树结构的嵌套单元格。这些单元格之一及其相应结构的示例如下图所示:
我想知道在Matlab中绘制相应结构的可能方法有哪些。到目前为止,我发现 this method here 这可能是可用的最佳解决方案,但我仍在努力实现它。谢谢
这样就不会没有答案了...
myCellArray = {0,0,{1,0,0,{1,0},0,0},{1,0,{1,0},0},{1,1},0,0};
[myTreeArray,myTreeEvals] = getTreeArray(myCellArray);
MYtreeplot(myTreeArray,myTreeEvals)
对于第四个示例输出,您可以根据需要进行修改:
两个函数,稍微改编自 SO 答案,如下所示。
首先基于@Wolfie 的
function [treearray, nodevals] = getTreeArray(cellarray)
% initialise the array construction from node 0
[nodes, ~, nodevals] = treebuilder(cellarray, 1,0);
nodevals = decellify(nodevals);
treearray = nodes-1;
% recursive tree building function, pass it a cell array and root node
function [out, node, nodevals] = treebuilder(cellarray, rnode,skipFirst)
% Set up variables to be populated whilst looping
out = []; nodevals = [];
% Start node off at root node
node = rnode;
% Loop over cell array elements, either recurse or add node
num2Loop = 1:numel(cellarray);
% ADDED, with input to function everywhere used
if skipFirst
num2Loop = 2:numel(cellarray);
end
%End ADDED
for ii = num2Loop
tb = []; node = node + 1;
if iscell(cellarray{ii})
[tb, node] = treebuilder(cellarray{ii}, node,1);
end
out = [out, rnode, tb];
end
nodevals = [nodevals,cellarray];
end
function data = decellify(data)
try
data = cellfun(@decellify,data,'un',0);
if any(cellfun(@iscell,data))
data = [data{:}];
end
catch
% a non-cell node, so simply return node data as-is
end
end
end
并基于此SO answer for treeplots:
function MYtreeplot(treearray,nodevals)
% At first we need to get the get the x and y coordinates of every node in the original tree plot and find all leaves in it
[x,y] = treelayout(treearray);
leaves = find( y == min(y) );
%ADDED
if nargin < 2
leaveParents = find( y ~= min(y) );
leaveChilds = leaves;
else
leaveParents = find([nodevals{:}]==1);
leaveChilds = find([nodevals{:}]~=1);
end
%END ADDED
num_layers = 1/min(y)-1;
chains = zeros(num_layers, length(leaves));
% Next, we reconstruct every chain in the tree plot and store it in a matrix (by doing so, we can later change the y position of the nodes)
for l=1:length(leaves)
index = leaves(l);
chain = [];
chain(1) = index;
parent_index = treearray(index);
j = 2;
while (parent_index ~= 0)
chain(j) = parent_index;
parent_index = treearray(parent_index);
j = j+1;
end
chains(:,l) = padarray(flip(chain), [0, num_layers-length(chain)], 'post');
end
% Now we compute the new y-coordinates determined by the row index in the matrix and dependent on the number of layers in the tree:
y_new = zeros(size(y));
for i=1:length(treearray)
[r,c] = find(chains==i, 1);
y_new(i) = max(y) - (r-1)*1/(num_layers+1);
end
% We can now plot the re-positioned nodes and add the connecting lines:
figure;plot(x(leaveParents), y_new(leaveParents), '.r','MarkerSize',16);
hold on
plot(x(leaveChilds), y_new(leaveChilds), '.k','MarkerSize',16);
for c=1:size(chains, 2)
line_x = x(chains(chains(:,c)>0, c));
line_y = y_new(chains(chains(:,c)>0, c));
line(line_x, line_y);
end
axis([0 1 0 1]);