Added source Matlab code for reference
This commit is contained in:
parent
b8af977117
commit
b5d99903d2
186 changed files with 61405 additions and 1 deletions
629
matlab/graph/@phyTree/Plot.m
Normal file
629
matlab/graph/@phyTree/Plot.m
Normal file
|
|
@ -0,0 +1,629 @@
|
|||
function handles = Plot(tr,varargin)
|
||||
%PLOT renders a phylogenetic tree.
|
||||
%
|
||||
% PLOT(TREE) renders a phylogenetic tree object into a MATLAB figure as a
|
||||
% phylogram. The significant distances between branches and nodes are in
|
||||
% horizontal direction, vertical coordinates are accommodated only for
|
||||
% display purposes. Handles to graph elements are stored in the
|
||||
% 'UserData' figure field, such that graphic properties can be easily
|
||||
% modified.
|
||||
%
|
||||
% PLOT(TREE,ACTIVEBRANCHES) hides the non'active branches and all their
|
||||
% descendants. ACTIVEBRANCHES is a logical array of size
|
||||
% [numBranches x 1] indicating the active branches.
|
||||
%
|
||||
% PLOT(...,'TYPE',type) selects the method to render the phylogenetic
|
||||
% tree. Options are: 'square' (default), 'angular', and 'radial'.
|
||||
%
|
||||
% PLOT(...,'ORIENTATION',orient) will orient the phylogenetic tree within
|
||||
% the figure window. Options are: 'top', 'bottom', 'left' (default), and,
|
||||
% 'right'. Orientation parameter is valid only for phylograms or
|
||||
% cladograms.
|
||||
%
|
||||
% PLOT(...,'BRANCHLABELS',value) hides/unhides branch labels. Options are
|
||||
% true or false. Branch labels are placed next to the branch node.
|
||||
% Defaults to false (true) when TYPE is (is not) 'radial'.
|
||||
%
|
||||
% PLOT(...,'LEAFLABELS',value) hides/unhides leaf labels. Options are
|
||||
% true or false. Leaf labels are placed next to the leaf nodes. Defaults
|
||||
% to false (true) when TYPE is (is not) 'radial'.
|
||||
%
|
||||
% PLOT(...,'TERMINALLABELS',value) hides/unhides terminal labels. Options
|
||||
% are true (default) or false. Terminal labels are placed over the axis
|
||||
% tick labels, ignored when 'radial' type is used.
|
||||
%
|
||||
% H = PLOT(...) returns a structure with handles to the graph elements.
|
||||
%
|
||||
% Example:
|
||||
%
|
||||
% tr = phytreeread('pf00002.tree')
|
||||
% plot(tr,'type','radial')
|
||||
%
|
||||
% % Graph element properties can be modified as follows:
|
||||
%
|
||||
% h=get(gcf,'UserData')
|
||||
% set(h.branchNodeLabels,'FontSize',6,'Color',[.5 .5 .5])
|
||||
%
|
||||
% See also PHYTREE, PHYTREE/VIEW, PHYTREEREAD, PHYTREETOOL, SEQLINKAGE.
|
||||
|
||||
% Copyright 2003-2006 The MathWorks, Inc.
|
||||
% $Revision: 1.1.6.10 $ $Author: batserve $ $Date: 2006/06/16 20:06:45 $
|
||||
|
||||
if numel(tr)~=1
|
||||
error('Bioinfo:phytree:plot:NoMultielementArrays',...
|
||||
'Phylogenetic tree must be an 1-by-1 object.');
|
||||
end
|
||||
|
||||
% set defaults
|
||||
dispBranchLabels = NaN;
|
||||
dispLeafLabels = NaN;
|
||||
dispTerminalLabels = true;
|
||||
renderType = 'square';
|
||||
orientation = 'left';
|
||||
rotation = 0;
|
||||
|
||||
tr = struct(tr);
|
||||
tr.numBranches = size(tr.tree,1);
|
||||
|
||||
if nargin>1 && islogical(varargin{1})
|
||||
activeBranches = varargin{1};
|
||||
argStart = 2;
|
||||
else
|
||||
activeBranches = true(tr.numBranches,1);
|
||||
argStart = 1;
|
||||
end
|
||||
|
||||
if nargin - argStart > 0
|
||||
if rem(nargin - argStart,2) == 1
|
||||
error('Bioinfo:phytree:plot:IncorrectNumberOfArguments',...
|
||||
'Incorrect number of arguments to %s.',mfilename);
|
||||
end
|
||||
okargs = {'type','orientation','rotation',...
|
||||
'branchlabels','leaflabels','terminallabels'};
|
||||
for j = argStart:2:nargin-argStart
|
||||
pname = varargin{j};
|
||||
pval = varargin{j+1};
|
||||
k = find(strncmpi(pname,okargs,numel(pname)));
|
||||
if isempty(k)
|
||||
error('Bioinfo:phytree:plot:UnknownParameterName',...
|
||||
'Unknown parameter name: %s.',pname);
|
||||
elseif length(k)>1
|
||||
error('Bioinfo:phytree:plot:AmbiguousParameterName',...
|
||||
'Ambiguous parameter name: %s.',pname);
|
||||
else
|
||||
switch(k)
|
||||
case 1 % type
|
||||
oktypes={'square','angular','radial'};
|
||||
l = strmatch(lower(pval),oktypes); %#ok
|
||||
if isempty(l)
|
||||
error('Bioinfo:phytree:plot:UnknownTypeName',...
|
||||
'Unknown option for %s.',upper(okargs{k}));
|
||||
else
|
||||
if l==4
|
||||
l=1;
|
||||
end
|
||||
renderType = oktypes{l};
|
||||
end
|
||||
case 2 % orientation
|
||||
oktypes={'left','right','top','bottom'};
|
||||
l = strmatch(lower(pval),oktypes); %#ok
|
||||
if isempty(l)
|
||||
error('Bioinfo:phytree:plot:UnknownOrientation',...
|
||||
'Unknown option for %s.',upper(okargs{k}));
|
||||
else
|
||||
orientation = oktypes{l};
|
||||
end
|
||||
case 3 % rotation
|
||||
if isreal(pval(1))
|
||||
rotation = double(pval(1));
|
||||
else
|
||||
error('Bioinfo:phytree:plot:NotValidType',...
|
||||
'ROTATION must be numeric and real');
|
||||
end
|
||||
case 4 % branch labels
|
||||
dispBranchLabels = opttf(pval);
|
||||
case 5 % leaf labels
|
||||
dispLeafLabels = opttf(pval);
|
||||
case 6 % terminal labels
|
||||
dispTerminalLabels = opttf(pval);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% set dependent defaults
|
||||
if isnan(dispBranchLabels)
|
||||
if isequal(renderType,'radial')
|
||||
dispBranchLabels = true;
|
||||
else
|
||||
dispBranchLabels = false;
|
||||
end
|
||||
end
|
||||
if isnan(dispLeafLabels)
|
||||
if isequal(renderType,'radial')
|
||||
dispLeafLabels = true;
|
||||
else
|
||||
dispLeafLabels = false;
|
||||
end
|
||||
end
|
||||
|
||||
tr = doBasicCalculations(tr,activeBranches,renderType);
|
||||
|
||||
nodeIndex = 1:tr.numLabels;
|
||||
leafIndex = 1:tr.numLeaves;
|
||||
branchIndex = tr.numLeaves+1:tr.numLabels;
|
||||
|
||||
|
||||
% check empty names
|
||||
for ind = nodeIndex
|
||||
if isempty(tr.names{ind})
|
||||
if ind > tr.numLeaves
|
||||
tr.names{ind} = ['Branch ' num2str(ind-tr.numLeaves)];
|
||||
else
|
||||
tr.names{ind} = ['Leaf ' num2str(ind)];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% rendering graphic objects
|
||||
fig = gcf;
|
||||
% fig = figure('Renderer','ZBuffer');
|
||||
h.fig = fig;
|
||||
h.axes = axes; hold on;
|
||||
sepUnit = max(tr.x)*[-1/20 21/20];
|
||||
|
||||
% setting the axes
|
||||
switch renderType
|
||||
case {'square','angular'}
|
||||
switch orientation
|
||||
case 'left'
|
||||
set(h.axes,'YTick',1:numel(tr.terminalNodes),'Ydir','reverse',...
|
||||
'YtickLabel','','YAxisLocation','Right')
|
||||
if dispTerminalLabels
|
||||
set(h.axes,'Position',[.05 .10 .7 .85])
|
||||
else
|
||||
set(h.axes,'Position',[.05 .10 .9 .85])
|
||||
end
|
||||
xlim(sepUnit);
|
||||
ylim([0 numel(tr.terminalNodes)+1]);
|
||||
case 'right'
|
||||
set(h.axes,'YTick',1:numel(tr.terminalNodes),'Xdir','reverse','Ydir','reverse',...
|
||||
'YtickLabel','','YAxisLocation','Left')
|
||||
if dispTerminalLabels
|
||||
set(h.axes,'Position',[.25 .10 .7 .85])
|
||||
else
|
||||
set(h.axes,'Position',[.05 .10 .9 .85])
|
||||
end
|
||||
xlim(sepUnit);
|
||||
ylim([0 numel(tr.terminalNodes)+1]);
|
||||
case 'top'
|
||||
set(h.axes,'XTick',1:numel(tr.terminalNodes),...
|
||||
'XtickLabel','','XAxisLocation','Top')
|
||||
if dispTerminalLabels
|
||||
set(h.axes,'Position',[.10 .05 .85 .7])
|
||||
else
|
||||
set(h.axes,'Position',[.10 .05 .85 .9])
|
||||
end
|
||||
ylim(sepUnit);
|
||||
xlim([0 numel(tr.terminalNodes)+1]);
|
||||
case 'bottom'
|
||||
set(h.axes,'XTick',1:numel(tr.terminalNodes),'Ydir','reverse',...
|
||||
'XtickLabel','','XAxisLocation','Bottom')
|
||||
if dispTerminalLabels
|
||||
set(h.axes,'Position',[.10 .25 .85 .7])
|
||||
else
|
||||
set(h.axes,'Position',[.10 .05 .85 .9])
|
||||
end
|
||||
ylim(sepUnit);
|
||||
xlim([0 numel(tr.terminalNodes)+1]);
|
||||
end
|
||||
case 'radial'
|
||||
set(h.axes,'XTick',[],'YTick',[])
|
||||
set(h.axes,'Position',[.05 .05 .9 .9])
|
||||
dispTerminalLabels = false;
|
||||
axis equal
|
||||
end
|
||||
|
||||
% drawing lines
|
||||
switch renderType
|
||||
case 'square'
|
||||
X = tr.x([nodeIndex;repmat([tr.par(1:tr.numLabels-1) tr.numLabels],2,1)]);
|
||||
Y = tr.y([repmat(nodeIndex,2,1);[tr.par(1:tr.numLabels-1) tr.numLabels]]);
|
||||
switch orientation
|
||||
case {'left','right'}
|
||||
h.BranchLines = plot(X,Y,'-k');
|
||||
delete(h.BranchLines(~tr.activeNodes))
|
||||
h.BranchLines = h.BranchLines(tr.activeNodes);
|
||||
case {'top','bottom'}
|
||||
h.BranchLines = plot(Y,X,'-k');
|
||||
delete(h.BranchLines(~tr.activeNodes))
|
||||
h.BranchLines = h.BranchLines(tr.activeNodes);
|
||||
end
|
||||
case 'angular'
|
||||
X = tr.x([nodeIndex;[tr.par(1:tr.numLabels-1) tr.numLabels]]);
|
||||
Y = tr.y([nodeIndex;[tr.par(1:tr.numLabels-1) tr.numLabels]]);
|
||||
switch orientation
|
||||
case {'left','right'}
|
||||
h.BranchLines = plot(X,Y,'-k');
|
||||
delete(h.BranchLines(~tr.activeNodes))
|
||||
h.BranchLines = h.BranchLines(tr.activeNodes);
|
||||
case {'top','bottom'}
|
||||
h.BranchLines = plot(Y,X,'-k');
|
||||
delete(h.BranchLines(~tr.activeNodes))
|
||||
h.BranchLines = h.BranchLines(tr.activeNodes);
|
||||
end
|
||||
case 'radial'
|
||||
R = tr.x;
|
||||
A = tr.y / numel(tr.terminalNodes)*2*pi+rotation*pi/180;
|
||||
tr.x = R .* sin(A);
|
||||
tr.y = R .* cos(A);
|
||||
X = tr.x([nodeIndex;[tr.par(1:tr.numLabels-1) tr.numLabels]]);
|
||||
Y = tr.y([nodeIndex;[tr.par(1:tr.numLabels-1) tr.numLabels]]);
|
||||
h.BranchLines = plot(X,Y,'-k');
|
||||
delete(h.BranchLines(~tr.activeNodes))
|
||||
h.BranchLines = h.BranchLines(tr.activeNodes);
|
||||
end
|
||||
|
||||
% drawing nodes
|
||||
switch renderType
|
||||
case {'square','angular'}
|
||||
switch orientation
|
||||
case {'left','right'}
|
||||
h.BranchDots = plot(tr.x(branchIndex(tr.activeNodes(branchIndex))),...
|
||||
tr.y(branchIndex(tr.activeNodes(branchIndex))),'o',...
|
||||
'MarkerSize',5,'MarkerEdgeColor','k',...
|
||||
'MarkerFaceColor','b');
|
||||
h.LeafDots = plot(tr.x(leafIndex(tr.activeNodes(leafIndex))),...
|
||||
tr.y(leafIndex(tr.activeNodes(leafIndex))),'square',...
|
||||
'MarkerSize',4,'MarkerEdgeColor','k',...
|
||||
'MarkerFaceColor','w');
|
||||
case {'top','bottom'}
|
||||
h.BranchDots = plot(tr.y(branchIndex(tr.activeNodes(branchIndex))),...
|
||||
tr.x(branchIndex(tr.activeNodes(branchIndex))),'o',...
|
||||
'MarkerSize',5,'MarkerEdgeColor','k',...
|
||||
'MarkerFaceColor','b');
|
||||
h.LeafDots = plot(tr.y(leafIndex(tr.activeNodes(leafIndex))),...
|
||||
tr.x(leafIndex(tr.activeNodes(leafIndex))),'square',...
|
||||
'MarkerSize',4,'MarkerEdgeColor','k',...
|
||||
'MarkerFaceColor','w');
|
||||
end
|
||||
case 'radial'
|
||||
h.BranchDots = plot(tr.x(branchIndex(tr.activeNodes(branchIndex))),...
|
||||
tr.y(branchIndex(tr.activeNodes(branchIndex))),'o',...
|
||||
'MarkerSize',5,'MarkerEdgeColor','k',...
|
||||
'MarkerFaceColor','b');
|
||||
h.LeafDots = plot(tr.x(leafIndex(tr.activeNodes(leafIndex))),...
|
||||
tr.y(leafIndex(tr.activeNodes(leafIndex))),'square',...
|
||||
'MarkerSize',4,'MarkerEdgeColor','k',...
|
||||
'MarkerFaceColor','w');
|
||||
end
|
||||
|
||||
% resize figure if needed
|
||||
switch renderType
|
||||
case {'square','angular'}
|
||||
switch orientation
|
||||
case {'left','right'}
|
||||
correctFigureSize(fig, 15 * numel(tr.terminalNodes),0);
|
||||
fontRatio = max(get(fig,'Position').*[0 0 0 1])/numel(tr.terminalNodes);
|
||||
case {'top','bottom'}
|
||||
correctFigureSize(fig, 0, 15 * numel(tr.terminalNodes));
|
||||
fontRatio = max(get(fig,'Position').*[0 0 1 0])/numel(tr.terminalNodes);
|
||||
end
|
||||
case 'radial'
|
||||
temp = 10/pi*numel(tr.terminalNodes);
|
||||
correctFigureSize(fig,temp,temp);
|
||||
fontRatio = max(get(fig,'Position').*[0 0 1 0])/numel(tr.terminalNodes);
|
||||
end
|
||||
|
||||
set(h.axes,'Fontsize',min(9,ceil(fontRatio/1.5)));
|
||||
|
||||
% set branch node labels
|
||||
X = tr.x(branchIndex(tr.activeNodes(tr.numLeaves+1:tr.numLabels)));
|
||||
Y = tr.y(branchIndex(tr.activeNodes(tr.numLeaves+1:tr.numLabels)));
|
||||
switch renderType
|
||||
case {'square','angular'}
|
||||
switch orientation
|
||||
case {'left'}
|
||||
h.branchNodeLabels = text(X+sepUnit(1)/2,Y,tr.names(branchIndex(tr.activeNodes(tr.numLeaves+1:tr.numLabels))));
|
||||
set(h.branchNodeLabels,'color',[0 0 .8],'clipping','on')
|
||||
set(h.branchNodeLabels,'vertical','bottom')
|
||||
set(h.branchNodeLabels,'horizontal','right')
|
||||
set(h.branchNodeLabels,'Fontsize',min(8,ceil(fontRatio/2)));
|
||||
case {'right'}
|
||||
h.branchNodeLabels = text(X+sepUnit(1)/2,Y,tr.names(branchIndex(tr.activeNodes(tr.numLeaves+1:tr.numLabels))));
|
||||
set(h.branchNodeLabels,'color',[0 0 .8],'clipping','on')
|
||||
set(h.branchNodeLabels,'vertical','bottom')
|
||||
set(h.branchNodeLabels,'Fontsize',min(8,ceil(fontRatio/2)));
|
||||
case {'top'}
|
||||
h.branchNodeLabels = text(Y,X-sepUnit(1)/2,tr.names(branchIndex(tr.activeNodes(tr.numLeaves+1:tr.numLabels))));
|
||||
set(h.branchNodeLabels,'color',[0 0 .8],'clipping','on')
|
||||
set(h.branchNodeLabels,'vertical','bottom','Rotation',30)
|
||||
set(h.branchNodeLabels,'Fontsize',min(8,ceil(fontRatio/2)));
|
||||
case {'bottom'}
|
||||
h.branchNodeLabels = text(Y,X+sepUnit(1)/2,tr.names(branchIndex(tr.activeNodes(tr.numLeaves+1:tr.numLabels))));
|
||||
set(h.branchNodeLabels,'color',[0 0 .8],'clipping','on')
|
||||
set(h.branchNodeLabels,'vertical','bottom','Rotation',30)
|
||||
set(h.branchNodeLabels,'Fontsize',min(8,ceil(fontRatio/2)));
|
||||
end
|
||||
case 'radial'
|
||||
h.branchNodeLabels = text(X,Y,tr.names(branchIndex(tr.activeNodes(tr.numLeaves+1:tr.numLabels))));
|
||||
set(h.branchNodeLabels,'color',[0 0 .8],'clipping','on')
|
||||
set(h.branchNodeLabels,'vertical','bottom')
|
||||
set(h.branchNodeLabels,'Fontsize',min(8,ceil(fontRatio*1.2)));
|
||||
for ind = 1:numel(h.branchNodeLabels)
|
||||
if X(ind)<0
|
||||
set(h.branchNodeLabels(ind),'horizontal','right')
|
||||
set(h.branchNodeLabels(ind),'Position',get(h.branchNodeLabels(ind),'Position')+[sepUnit(1)/2 0 0])
|
||||
else
|
||||
set(h.branchNodeLabels(ind),'horizontal','left')
|
||||
set(h.branchNodeLabels(ind),'Position',get(h.branchNodeLabels(ind),'Position')-[sepUnit(1)/2 0 0])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% set leaf nodes labels
|
||||
X = tr.x(leafIndex(tr.activeNodes(1:tr.numLeaves)));
|
||||
Y = tr.y(leafIndex(tr.activeNodes(1:tr.numLeaves)));
|
||||
switch renderType
|
||||
case {'square','angular'}
|
||||
switch orientation
|
||||
case {'left'}
|
||||
h.leafNodeLabels = text(X-sepUnit(1)/2,Y,tr.names(leafIndex(tr.activeNodes(1:tr.numLeaves))));
|
||||
set(h.leafNodeLabels,'color',[.5 .5 .5],'clipping','on')
|
||||
set(h.leafNodeLabels,'horizontal','left')
|
||||
set(h.leafNodeLabels,'Fontsize',min(8,ceil(fontRatio/2)));
|
||||
case {'right'}
|
||||
h.leafNodeLabels = text(X-sepUnit(1)/2,Y,tr.names(leafIndex(tr.activeNodes(1:tr.numLeaves))));
|
||||
set(h.leafNodeLabels,'color',[.5 .5 .5],'clipping','on')
|
||||
set(h.leafNodeLabels,'horizontal','right')
|
||||
set(h.leafNodeLabels,'Fontsize',min(8,ceil(fontRatio/2)));
|
||||
case {'top'}
|
||||
h.leafNodeLabels = text(Y,X-sepUnit(1)/2,tr.names(leafIndex(tr.activeNodes(1:tr.numLeaves))));
|
||||
set(h.leafNodeLabels,'color',[.5 .5 .5],'clipping','on')
|
||||
set(h.leafNodeLabels,'horizontal','left','Rotation',60)
|
||||
set(h.leafNodeLabels,'Fontsize',min(8,ceil(fontRatio/2)));
|
||||
case {'bottom'}
|
||||
h.leafNodeLabels = text(Y,X-sepUnit(1),tr.names(leafIndex(tr.activeNodes(1:tr.numLeaves))));
|
||||
set(h.leafNodeLabels,'color',[.5 .5 .5],'clipping','on')
|
||||
set(h.leafNodeLabels,'horizontal','right','Rotation',60)
|
||||
set(h.leafNodeLabels,'Fontsize',min(8,ceil(fontRatio/2)));
|
||||
end
|
||||
case 'radial'
|
||||
h.leafNodeLabels = text(X,Y,tr.names(leafIndex(tr.activeNodes(1:tr.numLeaves))));
|
||||
set(h.leafNodeLabels,'color',[.5 .5 .5],'clipping','on')
|
||||
set(h.leafNodeLabels,'Fontsize',min(8,ceil(fontRatio*1.2)));
|
||||
% textHeight = mean(cell2mat(get(h.leafNodeLabels,'Extent')))*[0 0 0 1]';
|
||||
for ind = 1:numel(h.leafNodeLabels)
|
||||
if X(ind)<0
|
||||
set(h.leafNodeLabels(ind),'horizontal','right')
|
||||
set(h.leafNodeLabels(ind),'Position',get(h.leafNodeLabels(ind),'Position')+[sepUnit(1) 0 0])
|
||||
else
|
||||
set(h.leafNodeLabels(ind),'horizontal','left')
|
||||
set(h.leafNodeLabels(ind),'Position',get(h.leafNodeLabels(ind),'Position')-[sepUnit(1) 0 0])
|
||||
end
|
||||
% a=atan(Y(ind)/X(ind))*180/pi;
|
||||
% if a > 0 a = max(0,a-60)/2; else
|
||||
% a = min(0,a+60)/2; end
|
||||
% set(h.leafNodeLabels(ind),'Rotation',a)
|
||||
end
|
||||
[sortedY,hsY]=sort(Y);
|
||||
idx=hsY(X(hsY)>0 & sortedY>0);
|
||||
if numel(idx)
|
||||
extentY = get(h.leafNodeLabels(idx(1)),'Extent')*[0;0;0;1];
|
||||
positionY = get(h.leafNodeLabels(idx(1)),'Position')*[0;1;0];
|
||||
for i = 2:numel(idx)
|
||||
position = get(h.leafNodeLabels(idx(i)),'Position');
|
||||
positionY = max(positionY+extentY,position(2));
|
||||
position(2) = positionY;
|
||||
set(h.leafNodeLabels(idx(i)),'Position',position)
|
||||
end
|
||||
end
|
||||
idx=hsY(X(hsY)<0 & sortedY>0);
|
||||
if numel(idx)
|
||||
extentY = get(h.leafNodeLabels(idx(1)),'Extent')*[0;0;0;1];
|
||||
positionY = get(h.leafNodeLabels(idx(1)),'Position')*[0;1;0];
|
||||
for i = 2:numel(idx)
|
||||
position = get(h.leafNodeLabels(idx(i)),'Position');
|
||||
positionY = max(positionY+extentY,position(2));
|
||||
position(2) = positionY;
|
||||
set(h.leafNodeLabels(idx(i)),'Position',position)
|
||||
end
|
||||
end
|
||||
idx=flipud(hsY(X(hsY)>0 & sortedY<0));
|
||||
if numel(idx)
|
||||
extentY = get(h.leafNodeLabels(idx(1)),'Extent')*[0;0;0;1];
|
||||
positionY = get(h.leafNodeLabels(idx(1)),'Position')*[0;1;0];
|
||||
for i = 2:numel(idx)
|
||||
position = get(h.leafNodeLabels(idx(i)),'Position');
|
||||
positionY = min(positionY-extentY,position(2));
|
||||
position(2) = positionY;
|
||||
set(h.leafNodeLabels(idx(i)),'Position',position)
|
||||
end
|
||||
end
|
||||
idx=flipud(hsY(X(hsY)<0 & sortedY<0));
|
||||
if numel(idx)
|
||||
extentY = get(h.leafNodeLabels(idx(1)),'Extent')*[0;0;0;1];
|
||||
positionY = get(h.leafNodeLabels(idx(1)),'Position')*[0;1;0];
|
||||
for i = 2:numel(idx)
|
||||
position = get(h.leafNodeLabels(idx(i)),'Position');
|
||||
positionY = min(positionY-extentY,position(2));
|
||||
position(2) = positionY;
|
||||
set(h.leafNodeLabels(idx(i)),'Position',position)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
% correct axis limits given the extent of labels
|
||||
if dispBranchLabels
|
||||
E = cell2mat(get(h.branchNodeLabels,'Extent'));
|
||||
if strcmp(get(gca,'XDir'),'reverse')
|
||||
E(:,1) = E(:,1) - E(:,3);
|
||||
end
|
||||
if strcmp(get(gca,'YDir'),'reverse')
|
||||
E(:,2) = E(:,2) - E(:,4);
|
||||
end
|
||||
E=[E;[xlim*[1;0] ylim*[1;0] diff(xlim) diff(ylim)]];
|
||||
mins = min(E(:,[1 2]));
|
||||
maxs = max([sum(E(:,[1 3]),2) sum(E(:,[2 4]),2)]);
|
||||
axis([mins(1) maxs(1) mins(2) maxs(2)])
|
||||
end
|
||||
|
||||
if dispLeafLabels
|
||||
E = cell2mat(get(h.leafNodeLabels,'Extent'));
|
||||
if strcmp(get(gca,'XDir'),'reverse')
|
||||
E(:,1) = E(:,1) - E(:,3);
|
||||
end
|
||||
if strcmp(get(gca,'YDir'),'reverse')
|
||||
E(:,2) = E(:,2) - E(:,4);
|
||||
end
|
||||
E=[E;[xlim*[1;0] ylim*[1;0] diff(xlim) diff(ylim)]];
|
||||
mins = min(E(:,[1 2]));
|
||||
maxs = max([sum(E(:,[1 3]),2) sum(E(:,[2 4]),2)]);
|
||||
axis([mins(1) maxs(1) mins(2) maxs(2)])
|
||||
end
|
||||
|
||||
% set terminal nodes labels
|
||||
switch renderType
|
||||
case {'square','angular'}
|
||||
X = tr.x(tr.terminalNodes) * 0;
|
||||
Y = tr.y(tr.terminalNodes);
|
||||
switch orientation
|
||||
case {'left'}
|
||||
X = X + max(xlim) - sepUnit(1)/2;
|
||||
h.terminalNodeLabels = text(X,Y,tr.names(tr.terminalNodes));
|
||||
case {'right'}
|
||||
X = X + max(xlim) - sepUnit(1)/2;
|
||||
h.terminalNodeLabels = text(X,Y,tr.names(tr.terminalNodes));
|
||||
set(h.terminalNodeLabels,'Horizontal','right')
|
||||
case {'top'}
|
||||
X = X + max(ylim) - sepUnit(1)/2;
|
||||
h.terminalNodeLabels = text(Y,X,tr.names(tr.terminalNodes));
|
||||
set(h.terminalNodeLabels,'Rotation',90)
|
||||
case {'bottom'}
|
||||
X = X + max(ylim) - sepUnit(1)/2;
|
||||
h.terminalNodeLabels = text(Y,X,tr.names(tr.terminalNodes));
|
||||
set(h.terminalNodeLabels,'Rotation',270)
|
||||
end
|
||||
case 'radial'
|
||||
h.terminalNodeLabels = text(0,0,' ');
|
||||
end
|
||||
|
||||
if dispTerminalLabels
|
||||
set(h.terminalNodeLabels,'Fontsize',min(9,ceil(fontRatio/1.5)));
|
||||
end
|
||||
|
||||
if ~dispBranchLabels
|
||||
set(h.branchNodeLabels,'visible','off');
|
||||
end
|
||||
if ~dispLeafLabels
|
||||
set(h.leafNodeLabels,'visible','off');
|
||||
end
|
||||
if ~dispTerminalLabels
|
||||
set(h.terminalNodeLabels,'visible','off');
|
||||
end
|
||||
|
||||
box on
|
||||
hold off
|
||||
|
||||
% store handles
|
||||
set(fig,'UserData',h)
|
||||
if nargout
|
||||
handles = h;
|
||||
end
|
||||
|
||||
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
function tr = doBasicCalculations(tr,activeBranches,renderType)
|
||||
|
||||
% helper function to compute and find some features of the tree
|
||||
tr.numLeaves = tr.numBranches + 1;
|
||||
tr.numLabels = tr.numBranches + tr.numLeaves;
|
||||
|
||||
% remove uderscores from names
|
||||
for ind = 1:tr.numLabels
|
||||
tr.names{ind}(tr.names{ind}=='_')=' ';
|
||||
end
|
||||
|
||||
% obtain parents for every node
|
||||
tr.par(tr.tree(:)) = tr.numLeaves + [1:tr.numBranches 1:tr.numBranches];
|
||||
|
||||
% find active nodes
|
||||
tr.activeNodes = true(tr.numLabels,1);
|
||||
for ind =tr.numBranches:-1:1
|
||||
tr.activeNodes(tr.tree(ind,:)) = tr.activeNodes(tr.numLeaves+ind) & activeBranches(ind);
|
||||
end
|
||||
|
||||
% propagate last leaf
|
||||
tr.lastleaf = 1:tr.numLabels;
|
||||
for ind = tr.numBranches:-1:1
|
||||
if ~tr.activeNodes(tr.tree(ind,1))
|
||||
tr.lastleaf(tr.tree(ind,:))=tr.lastleaf(ind+tr.numLeaves);
|
||||
end
|
||||
end
|
||||
|
||||
tr.activeBranches = tr.activeNodes(tr.numLeaves+1:tr.numLabels)&activeBranches;
|
||||
tr.activeLeaves = tr.activeNodes(1:tr.numLeaves);
|
||||
|
||||
% find x coordinates of branches
|
||||
tr.x = tr.dist;
|
||||
for ind = tr.numBranches:-1:1
|
||||
tr.x(tr.tree(ind,:)) = tr.x(tr.tree(ind,:)) + tr.x(ind+tr.numLeaves);
|
||||
end
|
||||
|
||||
% find y coordinates of branches
|
||||
tr.terminalNodes = tr.lastleaf([true,diff(tr.lastleaf(1:tr.numLeaves))~=0]);
|
||||
tr.y=zeros(tr.numLabels,1);
|
||||
tr.y(tr.terminalNodes)=1:length(tr.terminalNodes);
|
||||
switch renderType
|
||||
case 'square'
|
||||
for ind = 1:tr.numBranches
|
||||
if tr.activeBranches(ind)
|
||||
tr.y(ind+tr.numLeaves) = mean(tr.y(tr.tree(ind,:)));
|
||||
end
|
||||
end
|
||||
case {'angular','radial'}
|
||||
for ind = 1:tr.numBranches
|
||||
if tr.activeBranches(ind)
|
||||
if tr.x(tr.tree(ind,1))/tr.x(tr.tree(ind,2))>3
|
||||
tr.y(ind+tr.numLeaves) = tr.y(tr.tree(ind,1));
|
||||
elseif tr.x(tr.tree(ind,2))/tr.x(tr.tree(ind,1))>3
|
||||
tr.y(ind+tr.numLeaves) = tr.y(tr.tree(ind,2));
|
||||
else
|
||||
tr.y(ind+tr.numLeaves) = mean(tr.y(tr.tree(ind,:)));
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
function correctFigureSize(fig,recommendedHeight,recommendedWidth)
|
||||
% helper function to increase initial figure size depending on the screen &
|
||||
% tree sizes
|
||||
screenSize = diff(reshape(get(0,'ScreenSize'),2,2),[],2)-[0;100];
|
||||
% 100 gives extra space for the figure header and win toolbar
|
||||
position = get(fig,'Position');
|
||||
if recommendedHeight > position(4)
|
||||
if recommendedHeight < sum(position([2 4]))
|
||||
position(2) = sum(position([2 4])) - recommendedHeight;
|
||||
position(4) = recommendedHeight;
|
||||
elseif recommendedHeight < screenSize(2)
|
||||
position(2) = 30;
|
||||
position(4) = recommendedHeight;
|
||||
else
|
||||
position(2) = 30;
|
||||
position(4) = screenSize(2);
|
||||
end
|
||||
end
|
||||
if recommendedWidth > position(3)
|
||||
if recommendedWidth < sum(position([1 3]))
|
||||
position(1) = sum(position([1 3])) - recommendedWidth;
|
||||
position(3) = recommendedWidth;
|
||||
elseif recommendedWidth < screenSize(1)
|
||||
position(1) = 0;
|
||||
position(3) = recommendedHeight;
|
||||
else
|
||||
position(1) = 0;
|
||||
position(3) = screenSize(1);
|
||||
end
|
||||
end
|
||||
set(fig,'Position',position)
|
||||
Loading…
Add table
Add a link
Reference in a new issue