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

查看:26
本文介绍了使用树图将嵌套单元格绘制为树: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 以使其正确显示.

解决方案

我们可以创建一个递归函数,它探索你的元胞数组并创建一个树指针数组(如


您的元胞数组

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

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

这是

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.

解决方案

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:

  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:

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)


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

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

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