I have been working with MATLAB's treeplot function, but it seems to provide surprisingly little plotting functionality and/or extendibility.
I am plotting a tree like so:
tree = [0 1 2 2 2 2 2 1 8 8 1 11 11 1 14];
treeplot(tree)
Giving:
What I would like to do is add annotations or labels to specific nodes. A good starter would be to add the node numbers to each node, as in the example from the help file:
As they state, though:
These indices are shown only for the point of illustrating the example; they are not part of the treeplot output.
Is there a way to get the locations of the plotted nodes, or at the very least to plot the node numbers? I couldn't find any FEX submissions with more advanced tree plots.
Ultimately, I'd like to plot small pictures at the nodes (using methods from answers to a previous question of mine).
This should help you make a labeled tree:
(You supply the 'treeVec'.)
treeplot(treeVec);
count = size(treeVec,2);
[x,y] = treelayout(treeVec);
x = x';
y = y';
name1 = cellstr(num2str((1:count)'));
text(x(:,1), y(:,1), name1, 'VerticalAlignment','bottom','HorizontalAlignment','right')
title({'Level Lines'},'FontSize',12,'FontName','Times New Roman');
With your sample input, this gives
To get the position of the nodes, use treelayout
[x,y]=treelayout(tree);
The vectors x and y give you the positions, which you can then use to plot images at the nodes.
Related
I'm sure this is a trivial question for a signals person. I need to find the function in Matlab that outputs averaging of contiguous segments of windowsize= l of a vector, e.g.
origSignal: [1 2 3 4 5 6 7 8 9];
windowSize = 3;
output = [2 5 8]; % i.e. [(1+2+3)/3 (4+5+6)/3 (7+8+9)/3]
EDIT: Neither one of the options presented in How can I (efficiently) compute a moving average of a vector? seems to work because I need that the window of size 3 slides, and doesnt include any of the previous elements... Maybe I'm missing it. Take a look at my example...
Thanks!
If the size of the original data is always a multiple of widowsize:
mean(reshape(origSignal,windowSize,[]));
Else, in one line:
mean(reshape(origSignal(1:end-mod(length(origSignal),windowSize)),windowSize,[]))
This is the same as before, but the signal is only taken to the end minus the extra values less than windowsize.
Problem
I am trying to find the connected components of my undirected graph.
Matlabs function conncomp does exactly this. Mathworks - connected graph components
Example
Using the example given on matlabs webpage to keep it easy and repeatable:
G = graph([1 1 4],[2 3 5],[1 1 1],6);
plot(G)
bins = conncomp(G)
bins =
1 1 1 2 2 3
Two Question´s to this
First Question: Using this how can I find the initial node index, so that
cluster1 = (1 2 3); (instead of ( 1 1 1))
cluster2= (4 5); (instead of (2 2))
Second Question:
I am working on a big dataset and I know many nodes are not connected, so is there a way to only display clusters that contain more than one value ?
Thanks for your help, I am majorly stuck here.
You can use splitapply for the first part, like so:
clusters = splitapply(#(x) {x}, 1:numnodes(G), bins)
This returns a cell array where each cell contains the indices of the nodes in a group. You can filter this down in the usual way using cellfun
discard = cellfun(#isscalar, clusters);
clusters(discard) = [];
(Note that splitapply is new in R2015b - but the OP is using graph, also new in R2015b, so it should be fine for them)
Actually the first part of the question can be answered very simply as Matlabs conncomp provides a tool for this:
bins=conncomp(G,'OutputForm','cell');
Creates a cell array that contains the clusters, with all node names in the cells.
For the second part of the question I guess there are several ways but this one could be used as well:
clusters= bins(cellfun(#numel,bins)>1);
So I am writing a function that plots matrix data from n different cells. If n is 10, it should display 10 equally spaced plots on a single figure. If n is 7, it should try to space them out as equally as possible (so 3x2 or 2x3 plots with a plot by itself).
I am able to get these graphs drawn using subplot() and plot() but I'm having a hard time finding out how to initialise the dimensions for the subplot.
The number of subplots will be changing after each run so I can't initialise it to specific dimensions.
Can anyone point me in the right direction?
I am afraid problems like this tend to be messy. This normally problems like this need to be solved for different cases.
if (mod(n,2) && n<8)
% Do something
elseif (!mod(n,2) && n < 11)
% Do something else
elseif ...
....
end
The conditions are choosen a bit arbitarily since the specifications in the OP seemed a bit arbitary too. You probably understand the point and can set your own conditions.
There are two reasons why I recommend this approach.
1) This makes the code simpler to write. You do not have to come up with some complicated solution which may break in after some time.
2) By adding cases you can protect yourself against a rampant number of plots. In case the number of plots gets too large you do typically not want to have all plots in the same figure. It is also possible to wrap this into a function and apply this to X plots at a time in a loop. Typically you would want each iteration to be a separate figure.
It is not very easy to elaborate more on this since you have not yet specified how many cases you expect or what will happen to the last plot in case of odd numbers. Still this may give a good hint.
Good luck!
Another simple solution would be using round and ceil on the square root:
for n=1:20
[n, round(sqrt(n))*ceil(sqrt(n)), round(sqrt(n)), ceil(sqrt(n))]
end
output:
%(n, total_plots, x, y)
1 1 1 1
2 2 1 2
3 4 2 2
4 4 2 2
5 6 2 3
6 6 2 3
7 9 3 3
8 9 3 3
9 9 3 3
10 12 3 4
Usage example:
n = 7
subplot(round(sqrt(n)), ceil(sqrt(n)), plot_nr_x) % switch first 2 params to have either a slightly longer or slightly wider subplot
I ran into a very similar problem today and I was having a lot of trouble to define the size of the subplot that would fit everything. My reasoning is mostly a hack but it can help. If you have to represent at most n figures, you can thing as a square grid of sqrt(n) * sqrt(n). To make things better we add a safety row, so the final matrix would be (sqrt(n) + 1) * sqrt(n). I hope this helps solving your problem.
In my code have 2 nested loops:
within a loop that opens a figure for each kk element and is meant to plot a particular graph from the x position within the array.
for kk=1:length(some_file_list)
% Load data
% do some math
% get data as a cell array with things we care about in data(3,)
array_size = size(data(3,:),2);
for x=1:size(data(3,:),2);
% do more math and get things ready to plot matrix_A scaled by range_A
figure(kk); % open figure
grid_rows = round((sqrt(array_size)+1));
grid_cols = round(sqrt(array_size));
% plot
subplot(grid_rows, grid_cols, x);
imagesc(matrix_A,range_A); %plot in position
colormap(gray);
end
end
I have a 21x5 sized matrix (top5features) containing values for 5 different feature types extracted from 21 cancer nodules. I am trying to apply principal component analysis on my data and plotting the results, but am having trouble understanding how to do so. The following is my code so far, but it only plots a portion of the data and I do not believe it is what I am going for:
top5features = features(1:21,[42 55 61 62 60]);
[W, pc] = princomp(top5features);
pc = pc'; W = W';
plot(pc(1,:),pc(2,:),'.');
title('{\bf PCA} of Top 5 Features')
My goal is to make the plot so that it has 21 points, with each point pertaining to a specific nodule. These 21 nodules are also divided into two groups, and if possible I would like to color code them according to the group they belong to. I am somewhat of a beginner using Matlab and any help would be appreciated.
Given your comments, the first 10 columns of your PCA decomposed data denote one group while the last 11 columns of your PCA decomposed data denote another group. This can simply be done in a single plot command like so, using your code earlier:
%// Your code
top5features = features(1:21,[42 55 61 62 60]);
[W, pc] = princomp(top5features);
pc = pc'; W = W';
%// Group 1
group1 = pc(:,1:10);
%// Group 2
group2 = pc(:,11:21);
%// Plot as separate colours
plot(group1(1,:), group1(2,:), 'b.', group2(1,:), group2(2,:), 'r.');
title('{\bf PCA} of Top 5 Features')
legend('Group 1', 'Group 2');
The above code first separates your PCA reduced data into the two groups that you have specified. Next, we use a single plot command to plot both groups together on a single plot but we colour differentiate them. Blue is for group 1 while red is for group 2. We place dot markers at each of the points. As a bonus, we add in a legend that denotes which group each point belongs to.
Hope this helps!
I am currently working in matlab to design a way to reconstruct 3D data. For this I have two pictures with black points. The difference in the amount of points per frame is key for the reconstruction, but MATLAB gives an error when matrixes are not equal. This is happening becaus the code is not doing what I want it to do, so can anyone hel me with the following?
I have two columns of Xdata: XLI and XRI
What matlab does when I do XLI-XRI is substracting the pairs i.e XLI(1)-XRI(1) etc, but I want to substract each value of XRI of every value of XLI. i.e
XLI(1)-XRI(1,2,3,4 etc)
XLI(2)-XRI(1 2 3 4 etc)
and so on
Can anyone help?
I think you are looking for a way to deduct all combinations from eachother. Here is an example of how you can do that with bsxfun:
xLI = [1 2 3]
xRI = [1 2]
bsxfun(#minus,xLI ,xRI')
I cannot comment on Dennis's post (not enough points on this website) : his solution should work, but depending on your version of Matlab you might get a "Error using ==> bsxfun" and need to transpose either xLI or xRI for that to work :
bsxfun(#minus,xLI' ,xRI)
Best,
Tepp