使用treeplot将一个嵌套单元格绘制为一棵树:MATLAB(Ploting a nested cell as a tree using treeplot: MATLAB)

编程入门 行业动态 更新时间:2024-10-22 17:20:34
使用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以使其正确显示。

I have a complex cell that represents a tree structure:

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}};

I want to plot the representative tree from it by using treeplot(p), but I'm not sure how to construct the array p for it to display correctly.

最满意答案

我们可以创建一个递归函数,它探索您的单元格数组并为每个节点的父级创建一个树指针数组(如文档中所述)。

这个函数需要一个单元格数组(像你问题中的那个),它包含标量或嵌套单元数组。


treebuilder逻辑:

如果项目是标量,则为其分配一个父节点编号,将节点编号加1 如果某个项目是单元阵列, treebuilder在该单元上运行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}}))

这是输出图像 ,显示该算法可以处理更复杂的树。 速度看起来也不算太糟糕,尽管显示极其复杂的树木无论如何都是相当多余的!


编辑:标记节点

您可以通过使用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

注意 :如果您想对图上的每个节点编号,您可以使用类似的自适应来跟踪节点编号而不是节点

我在这里使用了一个单元格数组,以便在每个节点上都可以有文本或数值 。 如果你只想要数值,它可能会缩短后格式化来存储矩阵中的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} ,其中我选择了这些数字来表明它们不是实际的“节点号”!

在这里输入图像描述

We can create a recursive function, which explores your cell array and creates a tree pointer array (as described in the docs) to each node's parent.

This function takes a cell array (like the one in your question) which contains either scalars or nested cell arrays.


treebuilder logic:

If an item is a scalar, assign it a parent node number, increment node number by 1 If an item is a cell array, run treebuilder on that cell, returning the maximum node number which was reached (along with the generated sub-tree). Recursive function because of step 2, so repeat until every element done

Function:

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

Usage with simple example

Here is a more simple example than yours, so we can check logic works easily.

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)

simple


Your cell array

I think this works as expected, note you don't have to define the myCellArray or myTreeArray variables:

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}}))

Here is the output image, showing that the algorithm can cope with the more complicated tree. Speed doesn't seem too bad either, although displaying extremely complicated trees will be fairly redundant anyway!


Edit: Labelling the nodes

You can label the nodes by getting their position using treelayout and keeping track of the values as you encounter them when building the tree array. The function should be tweaked for this "keeping track" like so:

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

Note: You could use a similar adaptation to keep track of the node number instead of the node value if you wanted to number each node on the plot.

I have used a cell array here so that you could have text or numerical values on each node. If you only ever want numerical values, it may shorten the post-formatting to store nodevals in a matrix instead.

Then to plot this you can use

% 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);

Example output for the cell myCellArray = {{17, 99.9}, 50}, where I've chosen those numbers to make it clear they're not the actual "node number"!

enter image description here

更多推荐

本文发布于:2023-07-04 16:59:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1026900.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:嵌套   一棵树   单元格   treeplot   MATLAB

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!