使用 treeplot 将嵌套单元格绘制为树:MATLAB
Ploting a nested cell as a tree using treeplot: MATLAB
我有一个代表树结构的复杂单元格:
CellArray = {1,1,1,{1,1,1,{1,1,{1,{1 1 1 1 1 1 1 1}, 1,1}, 1,1},1,1,1},1,1,1,{1,1,1,1}};
我想使用 treeplot(p)
从中绘制代表树,但我不确定如何构造数组 p
以使其正确显示。
我们可以创建一个递归函数,它会探索您的元胞数组并为每个节点的父节点创建树指针数组(如 docs 中所述)。
此函数采用一个元胞数组(如您问题中的那个),其中包含标量或嵌套元胞数组。
treebuilder
逻辑:
- 如果某项是标量,则为其分配父节点编号,将节点编号递增 1
- 如果一个项目是一个元胞数组,运行
treebuilder
在那个元胞上,返回达到的最大节点数(连同生成的子树)。
- 由于第2步的递归函数,所以重复直到每个元素都完成
函数:
function treearray = getTreeArray(cellarray)
% initialise the array construction from node 0
treearray = [0, treebuilder(cellarray, 1)];
% recursive tree building function, pass it a cell array and root node
function [out, node] = treebuilder(cellarray, rnode)
% Set up variables to be populated whilst looping
out = [];
% Start node off at root node
node = rnode;
% Loop over cell array elements, either recurse or add node
for ii = 1:numel(cellarray)
tb = []; node = node + 1;
if iscell(cellarray{ii})
[tb, node] = treebuilder(cellarray{ii}, node);
end
out = [out, rnode, tb];
end
end
end
使用简单示例
这是一个比你的更简单的例子,所以我们可以很容易地检查逻辑是否正常。
myCellArray = {1 1 {1 1 1 {1 1 1}}};
% This cell array has 3 levels:
% - 3 child nodes (2,3,4) of the root node (1)
% - Last node on the first level (4) has 4 children:
% - 4 child nodes on second level (5,6,7,8)
% - Last node on the first level (8) has 3 children:
% - 3 child nodes on third level (9,10,11)
myTreeArray = getTreeArray(myCellArray);
% Output, we see the corresponding nodes as listed above:
% [0 1 1 1 4 4 4 4 8 8 8]
treeplot(myTreeArray)
你的元胞数组
我认为这符合预期,请注意您不必定义 myCellArray
或 myTreeArray
变量:
treeplot(getTreeArray({1,1,1,{1,1,1,{1,1,{1,{1 1 1 1 1 1 1 1}, 1,1}, 1,1},1,1,1},1,1,1,{1,1,1,1}}))
这里是output image,说明该算法可以应付更复杂的树。速度似乎也不错,尽管显示 极其 复杂的树无论如何都是相当多余的!
编辑:标记节点
您可以通过使用 treelayout
获取节点的位置来标记节点,并在构建树数组时跟踪遇到它们时的值。应该针对此“跟踪”调整功能,如下所示:
function [treearray, nodevals] = getTreeArray(cellarray)
% initialise the array construction from node 0
[nodes, ~, nodevals] = treebuilder(cellarray, 1);
treearray = [0, nodes];
% recursive tree building function, pass it a cell array and root node
function [out, node, nodevals] = treebuilder(cellarray, rnode)
% 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
for ii = 1:numel(cellarray)
node = node + 1;
if iscell(cellarray{ii})
[tb, node, nv] = treebuilder(cellarray{ii}, node);
out = [out, rnode, tb];
nodevals = [nodevals, nv];
else
out = [out, rnode];
nodevals = [nodevals, {node; cellarray{ii}}];
end
end
end
end
注意:您可以使用类似的改编来跟踪节点 number 而不是节点 value 如果你想对图上的每个节点进行编号。
我在这里使用了元胞数组,这样你可以在每个节点上有文本或数值。如果您只需要数值,它可能会缩短 post 格式以将 nodevals
存储在矩阵中。
然后绘制这个你可以使用
% Run the tree building script above
[treearray, nodevals] = getTreeArray(myCellArray);
% Plot
treeplot(treearray);
% Get the position of each node on the plot
[x,y] = treelayout(treearray);
% Get the indices of the nodes which have values stored
nodeidx = cell2mat(nodevals(1,:));
% Get the labels (values) corresponding to those nodes. Must be strings in cell array
labels = cellfun(@num2str, nodevals(2,:), 'uniformoutput', 0);
% Add labels, with a vertical offset to the y coords so that labels don't sit on nodes
text(x(nodeidx), y(nodeidx) - 0.03, labels);
单元格 myCellArray = {{17, 99.9}, 50}
的示例输出,其中我选择了这些数字以明确它们不是实际的“节点号”!
我有一个代表树结构的复杂单元格:
CellArray = {1,1,1,{1,1,1,{1,1,{1,{1 1 1 1 1 1 1 1}, 1,1}, 1,1},1,1,1},1,1,1,{1,1,1,1}};
我想使用 treeplot(p)
从中绘制代表树,但我不确定如何构造数组 p
以使其正确显示。
我们可以创建一个递归函数,它会探索您的元胞数组并为每个节点的父节点创建树指针数组(如 docs 中所述)。
此函数采用一个元胞数组(如您问题中的那个),其中包含标量或嵌套元胞数组。
treebuilder
逻辑:
- 如果某项是标量,则为其分配父节点编号,将节点编号递增 1
- 如果一个项目是一个元胞数组,运行
treebuilder
在那个元胞上,返回达到的最大节点数(连同生成的子树)。 - 由于第2步的递归函数,所以重复直到每个元素都完成
函数:
function treearray = getTreeArray(cellarray)
% initialise the array construction from node 0
treearray = [0, treebuilder(cellarray, 1)];
% recursive tree building function, pass it a cell array and root node
function [out, node] = treebuilder(cellarray, rnode)
% Set up variables to be populated whilst looping
out = [];
% Start node off at root node
node = rnode;
% Loop over cell array elements, either recurse or add node
for ii = 1:numel(cellarray)
tb = []; node = node + 1;
if iscell(cellarray{ii})
[tb, node] = treebuilder(cellarray{ii}, node);
end
out = [out, rnode, tb];
end
end
end
使用简单示例
这是一个比你的更简单的例子,所以我们可以很容易地检查逻辑是否正常。
myCellArray = {1 1 {1 1 1 {1 1 1}}};
% This cell array has 3 levels:
% - 3 child nodes (2,3,4) of the root node (1)
% - Last node on the first level (4) has 4 children:
% - 4 child nodes on second level (5,6,7,8)
% - Last node on the first level (8) has 3 children:
% - 3 child nodes on third level (9,10,11)
myTreeArray = getTreeArray(myCellArray);
% Output, we see the corresponding nodes as listed above:
% [0 1 1 1 4 4 4 4 8 8 8]
treeplot(myTreeArray)
你的元胞数组
我认为这符合预期,请注意您不必定义 myCellArray
或 myTreeArray
变量:
treeplot(getTreeArray({1,1,1,{1,1,1,{1,1,{1,{1 1 1 1 1 1 1 1}, 1,1}, 1,1},1,1,1},1,1,1,{1,1,1,1}}))
这里是output image,说明该算法可以应付更复杂的树。速度似乎也不错,尽管显示 极其 复杂的树无论如何都是相当多余的!
编辑:标记节点
您可以通过使用 treelayout
获取节点的位置来标记节点,并在构建树数组时跟踪遇到它们时的值。应该针对此“跟踪”调整功能,如下所示:
function [treearray, nodevals] = getTreeArray(cellarray)
% initialise the array construction from node 0
[nodes, ~, nodevals] = treebuilder(cellarray, 1);
treearray = [0, nodes];
% recursive tree building function, pass it a cell array and root node
function [out, node, nodevals] = treebuilder(cellarray, rnode)
% 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
for ii = 1:numel(cellarray)
node = node + 1;
if iscell(cellarray{ii})
[tb, node, nv] = treebuilder(cellarray{ii}, node);
out = [out, rnode, tb];
nodevals = [nodevals, nv];
else
out = [out, rnode];
nodevals = [nodevals, {node; cellarray{ii}}];
end
end
end
end
注意:您可以使用类似的改编来跟踪节点 number 而不是节点 value 如果你想对图上的每个节点进行编号。
我在这里使用了元胞数组,这样你可以在每个节点上有文本或数值。如果您只需要数值,它可能会缩短 post 格式以将 nodevals
存储在矩阵中。
然后绘制这个你可以使用
% Run the tree building script above
[treearray, nodevals] = getTreeArray(myCellArray);
% Plot
treeplot(treearray);
% Get the position of each node on the plot
[x,y] = treelayout(treearray);
% Get the indices of the nodes which have values stored
nodeidx = cell2mat(nodevals(1,:));
% Get the labels (values) corresponding to those nodes. Must be strings in cell array
labels = cellfun(@num2str, nodevals(2,:), 'uniformoutput', 0);
% Add labels, with a vertical offset to the y coords so that labels don't sit on nodes
text(x(nodeidx), y(nodeidx) - 0.03, labels);
单元格 myCellArray = {{17, 99.9}, 50}
的示例输出,其中我选择了这些数字以明确它们不是实际的“节点号”!