reordering dendrograms on a clustergram in matlab - matlab

I have generated a clustergram based on a dataset of normalized values, but I want to attempt to reorder the samples along the y-axis. I haven't come across much information on how to go about doing that after googling. Below is my code thus far: Any help would be appreciated.
[num, txt]= xlsread('S:\Breast\Breast Stats no post XRT.xls', 'Breast heat');
PID= txt(2:93,1);
varname = txt(1,2:23);
cgram = clustergram(num(1:92,:));
set(cgram,'Standardize',3,'Cluster',3, 'RowLabels',PID(:,:), 'ColumnLabels', varname(:,:),...
'Linkage','ward','Dendrogram',3,'ColumnPdist', 'euclidean', 'RowPdist', 'euclidean', 'OptimalLeafOrder', 'true',...
'SymmetricRange', 'false');
Also, does anyone know how to set the font size for the labels for ONE particular axis only?

About the main problem:
Suppose you put your data in nx2 a matrix A then you can sort it according to a column like this:
[Y,I]=sort(A(:,2)); % Sort by column 2 of the matrix
B=A(I,:); %use the indices from sort() to sort all rows of A.

To reorder the elements in the clustergram, you can set the OptimalLeafOrder property of the clustergram.
To set the font size for the labels, you can use the addXLabel or addYLabel commands, and then directly set the FontSize property of the text object returned.
See doc clustergram and doc addXLabel for more information and examples.

Related

Matlab function reshape doesnt´t calculate the last dimension while trying to create a 3D image from .raw binary image file

I created binarized images by using the Otsu methode in Matlab and cut out parts of the resulting image using a function. Now i want to take a look at these images with the VolumeViewer command. I know the x,y and z dimensions of the resulting imgages. I currently run this code doing it(excluding the volumeViewerwhich happens after the loop):
files= {'C3\C3_000mal_550_539_527.raw';...
};
for i=1:numel(files)
Image = fopen(files{i},'r');
ImageData{i} = fread(Image,Inf,'uint16=>uint16');
ImageData{i} = reshape(ImageData{i},550,539,[]);
fclose(openedCrystalImage);
end
Using this code runs into the following error using reshape:
Error using reshape
Product of known dimensions, 296450, not divisible into total number of elements, 78114575.
I did the maths and 550*539=296450 and 296450 * 527=156229150: If we divide the last number by the number of elements it equals 2 and thus is divisible into the total number of elements. In my opinion the reshape function is not able to find the size of the last dimension or defines it as 1.
Defining the size of z also results in an error suggesting using the brackets [], so the function can find it.
Error using reshape
Number of elements must not change. Use [] as one of the size inputs to automatically calculate the appropriate size
for that dimension.
Now to the weird part. This code works for another set of images, with diffrent sizes of the x,y and z ranges. So don´t know where the issue lies to be frank. So i would really appreciate and Answer to my question
I figured it out. The error lies here:
ImageData{i} = fread(Image,Inf,'uint16=>uint16');
Apparently by saving them as .raw before it converts the image to an 8 bit file rather than 16 bits it had before. Therefore, my dimension is double the size of the number of elements. With this alteration it works:
ImageData{i} = fread(Image,Inf,'uint8=>uint8');
The reason i was able to look at the other pictures was that the z range was divisble by 2.
So the reshape function was not the problem but size of the integer data while creating the array for the variable ImageData.
P.S. I just started out programming so the accuracy in the answer should be taken with a grain of salt

How to sum a matrix with unaligned elements?

I am trying to sum in the second dimension a matrix QI in Matlab. The trick is, the columns contain a series of increasing numbers, but not all columns have the same number of elements (i.e. numel(QI(:,1)) ~= numel(QI(:,2)) and so on). For the sake of clarity, I attach a picture of it. Note that I padded the missing areas with 0, so the previous condition becomes nnz(QI(:,1)) ~= nnz(QI(:,2)).
One initial strategy that I thought of was to treat this as an image and construct a mask for each different gradient level, but that seems like a tedious job.
Anyone has a better idea on how to do this? I should also mention that I am able to freely modify how QI is generated, but I'd rather not if there is a solution for this problem.
EDIT:
Hopefully the new colored image should give a better understanding.
FYI, each column was previously stored in a cell array without the trailing zeros. Then I extracted the columns one by one and stored them in a matrix in order to perform the summation, padding the extra zeros whenever the length isn't the same.
Generally these column data should have the same number of rows, but sometimes that's not the case, and even worse, they do not allign properly.
I'm starting to think if it's better to rework the code that generate the cell arrays rather than this matrix. Thoughts?
Thank you,
edit: following you comment, I modified the answer. Be aware that your data cannot be really "aligned" because they have not the same number of value.
A way would be to use a cell as a storage for your measures.
valueMissing = 0; % here you can put the defauld value you want
% transform you matrix in a cell
QICell = arrayfun(#(x) QI(QI(:,x)!=valueMissing,x), 1:size(QI,2),'UniformOutput', false);
Now you can sum the last element of the vectors inside the cell
QIsum = sum(cellfun(#(x) x(end), QICell))
Or reorder the vectors so that your last element are "aligned"
QICellReordered = cellfun(#(x) x(end:-1:1),QICell, 'UniformOutput',false);
Then you can make all possible sums:
m = min(cellfun(#numel, QICellReordered));
QIsum = zeros(m,1);
for i=1:m
QIsum(i) = sum(cellfun(#(x) x(i), QICellReordered));
end
% reorder QISum to your original order
QIsum = QIsum(end:-1:1);
I hope this help !

MATLAB: If this value of 5x5 cell with vectors [106x1] are different to zeroes,count them e put the count in a matrix

I have matchcounts (5x5)cell, every cell has a vector of double [106x1]. The vectors of double have zeros and non zero values. I want to find non zero values for every cell, count them and put the result in a matrix.
I tried with this code:
a{i,j}(k,1)=[];
for k=1:106
for i=1:5
for j=1:5
if (matchcounts{i,j}(k,1))~=0
a{i,j}=a{i,j}(k,1)+1;
end
end
end
end
and others but it's not correct! Can you help me? Thanks
While it is possible to fix your answer above, I recommend to change the data structure to have a much simpler solution possible. Instead of having a 2D cell array which holds 1D data, choose a single 3D data structure.
For an optimal solution you would change your previous code code to directly write the 3D-matrix, instead of converting it. To get started, this code converts it so you can already see how the data structure should look like:
%convert to matrix
for idx=1:numel(matchcounts)
matchcounts{idx}=permute(matchcounts{idx},[3,2,1]);
end
matchcounts=cell2mat(matchcounts);
And finding the nonzero elements:
a=(matchcounts~=0)
To index the result, instead of a{k,l}(m,1) you use a(k,l,m)
To give you some rule to avoid complicated data structures in the future. Use cell arrays only for string data and data of different size. Whenever you have a cell array which contains only vectors or matrices of the same size, it should be a multidimensional matrix.

Difference between hist and imhist in matlab

What is the difference between hist and imhist functions in Matlab? I have a matrix of color levels values loaded from image with imread and need to count entropy value of the image using histogram.
When using imhist the resulting matrix contains zeros in all places except the last one (lower-right) which contains some high value number (few thousands or so).
Because that output seems to be wrong, I have tried to use hist instead of imhist and the resulting values are much better, the matrix is fulfilled with correct-looking values instead of zeros.
However, according to the docs, imhist should be better in this case and hist should give weird results..
Unfortunately I am not good at Matlab, so I can not provide you with better problem description. I can add some other information in the future, though.
So I will try to better explain my problem..I have an image, for which I should count entropy and few other values (how much bytes it will take to save that image,..). I wrote this function and it works pretty well
function [entropy, bytes_image, bytes_coding] = entropy_single_pixels(im)
im = double(im);
histg = hist(im);
histg(histg==0) = [];
nzhist = histg ./ numel(im);
entropy = -sum(nzhist.*log2(nzhist));
bytes_image = (entropy*(numel(im))/8);
bytes_coding = 2*numel(unique(im));
fprintf('ENTROPY_VALUE:%s\n',num2str(entropy));
fprintf('BYTES_IMAGE:%s\n',num2str(bytes_image));
fprintf('BYTES_CODING:%s\n',num2str(bytes_coding));
end
Then I have to count the same, but I have to make "pairs" from pixels which are below each other. So I have only half the rows and the same count of columns. I need to express every unique pixel pair as a different number, so I multiplied the first one by 1000 and added the second one to it... Subsequently I need to actually apply the same function as in the first example, but that is the time, when I am getting weird numbers from the imhist function. When using hist, it seems to be OK, but I really don't think that behavior is correct, so that must be my error somewhere. I actually understand pretty good, to what I want to do, or at least I hope so, but unfortunately Matlab makes all that kind of hard for me :)
hist- compute histogram(count number of occurance of each pixel) in color image.........
imhist- compute histogram in two dimensional image.
Use im2double instead of double if you want to use imhist. The imhist function expects double or single-precision data to be in the [0,1] data range, which is why you see everything in the last bin of the histogram.

Matlab boxplot for multiple fields

I have this matlab file which has a field called "data". In "data" I have lots of fields for different bonds (x5Q12... etc).
I am trying to produce ONE box plot that contains ONE column from each of the fields (i.e. a box diagram with 36 boxes in it). I tried this code (e.g. to plot a box for column 2 in all of the bonds) but it does't work for me:
boxplot(gilts_withoutdates.data.:(:,2));figure(gcf);
I know my understanding of calling different levels in a structure is a problem here. Any suggestions, please? Many thanks.
You can use STRUCTFUN to extract the data from a particular column of all fields of a structure.
col2plot = 2; %# this is the column you want to plot
%# return, for each field in the structure, the specified
%# column in a cell array
data2plot = structfun(#(x){x(:,col2plot)},gilts_withoutdates.data);
%# convert the cell array into a vector plus group indices
groupIdx = arrayfun(#(x)x*ones(size(data2plot{x})),1:length(data2plot),'uni',0);
groupIdx = cat(1,groupIdx{:});
data2plot = cat(1,data2plot{:});
%# create a compact boxplot
boxplot(data2plot,groupIdx,'plotStyle','compact','labels',labels)
If you're interested in the distribution of the data, I can recommend my function distributionPlot.
B=gilts_withoutdates.data;
b=fieldnames(B);
for a=1:numel(b)
boxplot(B.(b{a})); fig;
end
To plot a boxplot for each of the 5 columns of data for each field you could do this:
pos=1;
for i = 1:numel(b)
for ii=1:5
subplot(numel(b),5,pos);boxplot(B.(b{i})(:,ii));pos=pos+1;
end
end