使用树形图将嵌套的单元格绘制为树:MATLAB [英] Ploting a nested cell as a tree using treeplot: MATLAB

查看:131
本文介绍了使用树形图将嵌套的单元格绘制为树:MATLAB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个表示树结构的复杂单元格:

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

我想使用treeplot(p)从中绘制代表树,但是我不确定如何构造数组p使其正确显示.

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.

推荐答案

我们可以创建一个递归函数,该函数探索您的单元格数组并创建树指针数组(如

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.

  1. 如果某项是标量,则为其分配一个父节点号,将节点号增加1
  2. 如果某项是单元格数组,请在该单元格上运行treebuilder,返回已达到的最大节点数(以及生成的子树).
  3. 因为有第2步,所以需要递归函数,所以请重复执行直到每个元素完成
  1. If an item is a scalar, assign it a parent node number, increment node number by 1
  2. 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).
  3. Recursive function because of step 2, so repeat until every element done


功能:

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)

我认为这可以按预期工作,请注意,您不必定义myCellArraymyTreeArray变量:

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!

您可以通过使用 treelayout 来获取节点的位置来标记节点a>并在构建树数组时跟踪遇到的值.应该针对此跟踪"功能进行调整,如下所示:

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

注意:如果您希望为每个节点编号,则可以使用类似的修改来跟踪节点 number 而不是节点 value 图上的节点.

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.

我在这里使用了一个单元格数组,以便您可以在每个节点上输入文本或数字值.如果您只想使用数值,则可以缩短后格式,以将nodevals存储在矩阵中.

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

单元格myCellArray = {{17, 99.9}, 50}的示例输出,在这里我选择了这些数字以使其清楚不是实际的节点号"!

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"!

这篇关于使用树形图将嵌套的单元格绘制为树:MATLAB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆