TreePlot String Labeling MATLAB - matlab

nodes = [0 1 2 3 4 4 3 7 7 2 10 11 11 10 14 14 1 17 18 19 19 18 22 22 17 25 26 26 25 29 29]; This is the standard plot for a depth 4 tree. It is in a loop, and gets drawn 10 times. Now, each of these 10 times some numerical computations are done and different numbers are come up with. These numbers all point to some word tags in a main array. Each time these numbers change, the words indexed also change, and I already know how they are to be placed in the tree. How do I label the tree with these strings then ?
I guess, the general question is how to label a tree with a bunch of strings?

A bit of a hack is to look at plotted points and, assuming they have a 1-1 correspondence with the nodes in your vector, use their coordinates to plot text.
treeplot([0 1 1]); % plot your tree
c = get(gca, 'Children'); % get handles to children
% grab X and Y coords from the second child (the first one is axes)
x = get(c(2), 'XData');
y = get(c(2), 'YData');
Now you can plot whatever at these coordinates. If labels is a cell array of labels, then you can display them next to the nodes as follows:
text(x, y, labels, 'VerticalAlignment','bottom', ...
'HorizontalAlignment','right')

Related

Color some samples of MATLAB figure with different color

I have a discrete signal x of length N traced in MATLAB using the command
stem(abs(x)); axis([0 N+6 0 4]);
The resulted figure is shown below:
My question I need only some values corresponding for example to index [7 10 11 12 15 18 48 50 52 60] to be colored with different color , let's say with red.
How can I do that into my figure ?
Using Multiple Plots by hold on and Matrix Indexing
You could possibly and alternatively place a plot on top of plot by using hold on. This does require an adjustment where you need a vector in this case Sample and Indices which specify the sample number/data point index. You can also use matrix indexing to get the amplitude/data points corresponding to the key point, Indicies.
%Vector relating to the sample/data point number%
Sample = linspace(1,70,70);
%Random test data%
X = randi([0,2],1,70);
stem(Sample,X);
hold on
%Key indices to change colour%
Key_Indices = [7 10 11 12 15 18 48 50 52 60];
%Matrix indexing to get values/amplitudes corresponding to key indices%
X_Prime = X(Key_Indices);
stem(Key_Indices,X_Prime,'r');
axis([0 70 0 3]);
hold off
Ran using MATLAB R2019b
This code makes just the circles red and not the stems
plot with selected red circles
%Vector relating to the sample/data point number
Sample = linspace(1,70,70);
%Random test data
X = randi([0,2],1,70);
stem(Sample,X);
%Key indices to change color
Key_Indices = [7 10 11 12 15 18 48 50 52 60];
line(Sample(Key_Indices), X(Key_Indices), 'linestyle', 'none', 'marker', 'o', 'color', 'r')
axis([0 70 0 3])
grid on

Fraction of overlapping members across multiple vectors

I have a cell M with n number of cells, with each cell containing several unique numbers, something like this:
{[15 16 21 26 28 145],[2 5 8 9 15],[20 24 27],[10 11 15 8 6 258 74 1],...}
Some of these values appear in more than 1 cell. I would like to calculate the fraction of overlapping values across these cells. For instance, with the 4 cells above, I have 19 unique numbers, and 2 of them belong to more than 1 cell: 15 and 8. Thus, the fraction of overlapping cell is 2/19 = .105. Note that the number of cells in M can vary and thus the number of unique numbers in M also vary as well. Does anyone have any suggestion on how to do this efficiently? I've tried horzcat to concatenate the cells within M then used unique but didn't quite get what I want.
Using the output of the hist() function is useful here.
M = {[15 16 21 26 28 145],[2 5 8 9 15],[20 24 27],[10 11 15 8 6 258 74 1]};
% Bring data to one matrix.
M2 = cell2mat(M);
% Build a histogram from the data with a bin on each unique element. The
% first output of hist is the number of elements in each bin.
a = hist(M2,unique(M2));
% Calculate the overlap by dividing the number of elements that occur more
% than once by the total number of elements.
overlap = sum(a>1)/numel(a);

plot a curve as smaller parts, matlab

I have a sequence of points i wish to plot, but the resultant curve could be broken at places if the points are too far apart.
So in the 1D CASE :
1 2 3 7 9 11 12 16 18 19
Would be like :
1-2-3 7-9-11-12 16-18-19
or : seq1 seq2 seq3
I want to plot my sequence as discrete parts seq1 seq2 and seq3 which are not connected.
I am not too sure how to go about this
sea the code snippet below for a solution of your problem. I tried to explain as much in the code as possible, but don't hesitate to ask, if anything is not clear.
% constants, thresold defintion
T = 4;
% your data
a = [1 2 3 7 9 11 12 16 18 19 24 25 26 28 35 37 38 39];
% preparing the x-axis
x = 1:length(a);
% Getting the differences between the values
d = diff(a);
% find the suggested "jumps/gaps", greater/equal than the threshold
ind = find(d>=T);
figure;
hold on;
% Plotting the first part of a
y = nan*ones(1,length(a));
y(1:ind(1)) = a(1:ind(1));
plot(x,y);
% Plotting all parts in between: go through all found gaps
% and plot the corresponding values of "a" between them
for j=2:length(ind)
y = nan*ones(1,length(a));
y(ind(j-1)+1:ind(j)) = a(ind(j-1)+1:ind(j));
plot(x,y);
end;
% Plotting the last part of a
y = nan*ones(1,length(a));
y(ind(j)+1:end) = a(ind(j)+1:end);
plot(x,y);

Matlab: modify each cube of 3D cell matrix

I have used mat2cell to create a 12 x 13 x 5 cell matrix where each cell contains a 29 x 29 x 29 cube.
How do I generate a new 3D cell matrix containing only the central 21 x 21 x 21 cube of each 29 x 29 x 29 cube?
i.e. so the new matrix is still 12 x 13 x 5 but each one contains a 21 x 21 x 21 of central voxels of original cube?
To crop an indivual block, you can use a simple indexing expression:
c=4 % cut of c rows on each side.
for ix=1:numel(X)
X{ix}=X{ix}(1+c:end-c,1+c:end-c,1+c:end-c);
end
If you are aiming for a solution with a better Performance, I recommend switching to multi dimensional matrices:
c=4
Y=reshape(X,29,12,29,13,29,5);
%now the first block is squeeze(Y(:,1,:,1,:,1))
%now cut to smaller blocks:
Y=Y(1+c:end-c,:,1+c:end-c,:,1+c:end-c,:);

how to find the middle elements of sub matrices in a matrix

I have a matrix and i want to consider it has 4 sub matrices which are placed together. How can I find the middle element of each sub matrix when they are together?
consider the matrix below. It is built by 4 sub matrices.
1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18
19 20 21 22 23 24
25 26 27 28 29 30
31 32 33 34 35 36
I want to get their middle elements so i could have:
8, 11, 26, 29
From what I have understood this might work for you and this is a demo, so use your own parameters -
Code
%%// Input matrix
A = rand(44,44);
%%/ Number of submatrices needed
num_submat = 16;%%// 4 for your example case
%%/ Number of submatrices along row and column
num_submat1= sqrt(num_submat);
%%// Middle element indices along each direction
v1 = floor(size(A,2)/(2*num_submat1))+1:size(A,2)/(num_submat1):size(A,2);
%%// Middle elements
middle_ele = A(v1,v1)
It is always helpful to know that matrix indexing in matlab goes columnwise eg,
indOrd = [1,4,7;2,5,8;3,6,9]
where the number is the index order and not related to your example. indOrd(4) would return 4. Try to use this to find the index locations.
Assuming that each submatrix has odd size 2n+1, the coordinates of the center of one submatrix alone are [n+1, n+1]. If your have a square with M*M submatrices (M=2 in your case), the coordinates are [n+1+i*(2*n+1), n+1+j*(2*n+1)], i and j taken independently in the range 0:M-1.
Turning back to Matlab, it is now quite easy to generate all indices of the centers of the submatrices grouped in the matrix A:
n = floor(size(A,1)/(2*M));
xc = n+1+reshape(repmat(0:M-1,M,1),[],1);
yc = n+1+reshape(repmat((0:M-1)',1,M),[],1);
centers = A(yc, xc);
For even-sized submatrix, you have to choose which element is the center, the modification is quite easy to do then.