plot an mdscaled matrix of points - matlab

I have a 151-by-200 matrix, let's say D, where rows are patients and cols are some features.
After using pdist and mdscale I obtain a 151-by-3 matrix. I also used some consensus clustering algorithm and obtained the partitioning of the patients.
Now I would like to plot the distribution of the mdscaled matrix of points, each one with a shape and a colour (where shapes indicates classes and colors clusters ) as in the image below.
Can you give me an hint on how to do it? Thank you.

Here is an example how to plot grouped 3D points:
% data and clusters
load fisheriris
X = meas(:,1:3);
[L,~,Y] = unique(species);
% colors and markers of each group
colors = hsv(numel(L));
markers = 'osdv^x*+.><ph';
% plot
for i=1:numel(L)
ind = (Y == i);
h(i) = line(X(ind,1), X(ind,2), X(ind,3), ...
'LineStyle','none', 'LineWidth',1, 'MarkerSize',8, ...
'Marker',markers(i), 'Color',colors(i,:), ...
'MarkerEdgeColor','k', 'MarkerFaceColor',colors(i,:));
end
view(-150,30), axis vis3d, grid on, box on
legend(h, L, 'Location','northeast')
title('MultiDimensional Scaling')
xlabel('dim1'), ylabel('dim2'), zlabel('dim3')
You can customize the shapes and colors to match your criteria ("shapes indicates classes and colors clusters").

Related

Plot confusion matrix

I want to plot a confusion matrix in MATLAB. Here's my code;
data = rand(3, 3)
imagesc(data)
colormap(gray)
colorbar
When I run this, a confusion matrix with a color bar is shown. But usually, I have seen confusion matrix in MATLAB will give counts as well as probabilities. How can I get them? How can I change the class labels which will be shown as 1,2,3, etc.?
I want a matrix like this:
If you do not have the neural network toolbox, you can use plotConfMat. It gets you the following result.
I have also included an independent example below without the need for the function:
% sample data
confmat = magic(3);
labels = {'Dog', 'Cat', 'Horse'};
numlabels = size(confmat, 1); % number of labels
% calculate the percentage accuracies
confpercent = 100*confmat./repmat(sum(confmat, 1),numlabels,1);
% plotting the colors
imagesc(confpercent);
title('Confusion Matrix');
ylabel('Output Class'); xlabel('Target Class');
% set the colormap
colormap(flipud(gray));
% Create strings from the matrix values and remove spaces
textStrings = num2str([confpercent(:), confmat(:)], '%.1f%%\n%d\n');
textStrings = strtrim(cellstr(textStrings));
% Create x and y coordinates for the strings and plot them
[x,y] = meshgrid(1:numlabels);
hStrings = text(x(:),y(:),textStrings(:), ...
'HorizontalAlignment','center');
% Get the middle value of the color range
midValue = mean(get(gca,'CLim'));
% Choose white or black for the text color of the strings so
% they can be easily seen over the background color
textColors = repmat(confpercent(:) > midValue,1,3);
set(hStrings,{'Color'},num2cell(textColors,2));
% Setting the axis labels
set(gca,'XTick',1:numlabels,...
'XTickLabel',labels,...
'YTick',1:numlabels,...
'YTickLabel',labels,...
'TickLength',[0 0]);
If you have the neural network toolbox you can use the function plotconfusion. You can create a copy and edit it to customise it further, for example to print custom labels.

Matlab - multiple variables normalized histogram?

I'm working on MATLAB, where I have a vector which I need to split into two classes and then get a histogram of both resulting vectors (which have different sizes). The values represent height records so the interval is about 140-185.
How can I get a normalized histogram of both resulting vectors in different colors. I was able to get both normalized vectors in the same colour (which is indistiguible) and and also a histogram with different colours but not not normalized...
I hope you understand my question and will be able to help me.
Thanks in advance :)
Maybe this is what you need:
matrix = [155+10*randn(2000,1) 165+10*randn(2000,1)];
matrix(1:1100,1) = NaN;
matrix(1101:2000,2) = NaN; %// example data
[y x] = hist(matrix, 15); %// 15 is desired number of bins
y = bsxfun(#rdivide, y, sum(y)) / (x(2)-x(1)); %// normalize to area 1
bar(x,y) %// plots each column of y vs x. Automatically uses different colors

Plot vectors with labels in matlab

I have a Nx62 matrix with N 62-D vectors and a NX1 vector with the labels for the vectors. I am trying to plot these vectors with their labels because I want to see the behavior of these classes when plotted in a 62-dimensional space. The vectors belong to three classes according to the labels of a NX1 vector cited before.
How to to that in matlab? when i do plot(vector,classes) the result is very weird to analyse, how to put labels in the graph?
The code i am using to get the labels, vectors and plotting is the following:
%labels is a vector with labels, vectors is a matrix where each line is a vector
[labels,vectors]=libsvmread('features-im1.txt');
when I plot a three dimensional vector is simple
a=[1,2,3]
plot(a)
and then I get the result
but now i have a set of vectors and a set of labels, and i want to see the distribution of them, i want to plot each of these labels but also want to identify their classes. How to do that in matlab?
EDIT: This code is almost working. The problem is the fact that for each vector and class the plot will assign a color. I just want three colors and three labels, one per class.
[class,vector]=libsvmread('features-im1.txt');
%the plot doesn't allow negative and 0 values in the label
class=class+2;
labels = {'class -1','class 0','class 1'};
h = plot(vector);
legend(h,labels{class})
If I understand correctly, this does what you want:
N = 5;
classes = [1 2 3 1 2]; % class of each vector. Size N x 1
colors = {'r', 'g', 'b'}; % you can also define them numerically
matrix = rand(N,62); % example data. Size N x 62
labels = {'class 1','class 2','class 3'}; % class names. Size max(classes) x 1
h = plot(matrix.');
h_first = NaN(1,3); % initialization
for k = 1:max(classes)
ind = find(classes==k);
set(h(ind), 'color', colors{k}) % setting color to all plots of a given class
h_first(k) = h(ind(1)); % remember a handle of each color (for legend)
end
legend(h_first,labels)

How can I create a plot like this in MATLAB?

I am trying to plot the ranges of different cellular base stations in MATLAB, like this:
But I can't figure out how to do it.
Here's an example of how you can create a plot like this. Note that I created sample data for the plot by randomly generating the positions of cellular base stations using uniformly distributed pseudorandom numbers:
%# Initializations:
minRange = 0; %# Lower x and y range
maxRange = 3.5; %# Upper x and y range
resolution = 1000; %# The number of data points on the x and y axes
cellRange = linspace(minRange, maxRange, resolution);
[x, y] = meshgrid(cellRange); %# Create grids of x and y coordinates
cellCoverage = zeros(size(x)); %# Initialize the image matrix to zero
%# Create the sample image data:
numBases = 200;
cellRadius = 0.75;
for iBase = 1:numBases
point = rand(1,2).*(maxRange - minRange) + minRange;
index = ((x - point(1)).^2 + (y - point(2)).^2) <= cellRadius^2;
cellCoverage(index) = cellCoverage(index) + 1;
end
%# Create the plot:
imagesc(cellRange, cellRange, cellCoverage); %# Scaled plot of image data
axis equal; %# Make tick marks on each axis equal
set(gca, 'XLim', [minRange maxRange], ... %# Set the x axis limit
'YLim', [minRange maxRange], ... %# Set the y axis limit
'YDir', 'normal'); %# Flip the y axis direction
xlabel('X-distance (km)'); %# Add an x axis label
ylabel('Y-distance (km)'); %# Add a y axis label
colormap(jet); %# Set the colormap
colorbar; %# Display the color bar
And here's the resulting plot:
Note also that the data in the image matrix cellCoverage contains no noise and has no smoothing applied, which is why the edges appear sharper than the original image in the post (which I'm guessing is generated from real data, not "fake" sample data like I used here).
Use "image"
image(x),colormap(hsv) <- where x is a matrix of cellular intensities(x,y)
You need to get the coordinate of each station then create a circle polygon around it (with a given radius), then convert this polygon into a grid. Then you sum up these grids (matrices) on top of each other. For speed, instead of using polygons you can also define which cells will be covered by a station, like all cells within 5 rows or columns of a station get the value.
You can also apply a 2D Gaussian filter to your matrix, where only the cells containing a station have a value of 1. The bandwidth of your Gaussian kernel will be your coverage radius (range). http://www.mathworks.ch/help/toolbox/images/ref/fspecial.html

MATLAB: draw centroids

My main question is given a feature centroid, how can I draw it in MATLAB?
In more detail, I have an NxNx3 image (an RGB image) of which I take 4x4 blocks and compute a 6-dimensional feature vector for each block. I store these feature vectors in an Mx6 matrix on which I run kmeans function and obtain the centroids in a kx6 matrix, where k is the number of clusters and 6 is the number of features for each block.
How can I draw these center clusters in my image in order to visualize if the algorithm is performing the way I wish it to perform? Or if anyone has any other way/suggestions on how I can visualize the centroids on my image, I'd greatly appreciate it.
Here's one way you can visualize the clusters:
As you described, first I extract the blocks, compute the feature vector for each, and cluster this features matrix.
Next we can visualize the clusters assigned to each block. Note that I am assuming that the 4x4 blocks are distinct, this is important so that we can map the blocks to their location back in the original image.
Finally, in order to display the cluster centroids on the image, I simply find the closest block to each cluster and display it as a representative of that cluster.
Here's a complete example to show the above idea (in your case, you would want to replace the function that computes the features of each block by your own implementation; I am simply taking the min/max/mean/median/Q1/Q3 as my feature vector for each 4x4 block):
%# params
NUM_CLUSTERS = 3;
BLOCK_SIZE = 4;
featureFunc = #(X) [min(X); max(X); mean(X); prctile(X, [25 50 75])];
%# read image
I = imread('peppers.png');
I = double( rgb2gray(I) );
%# extract blocks as column
J = im2col(I, [BLOCK_SIZE BLOCK_SIZE], 'distinct'); %# 16-by-NumBlocks
%# compute features for each block
JJ = featureFunc(J)'; %'# NumBlocks-by-6
%# cluster blocks according to the features extracted
[clustIDX, ~, ~, Dist] = kmeans(JJ, NUM_CLUSTERS);
%# display the cluster index assigned for each block as an image
cc = reshape(clustIDX, ceil(size(I)/BLOCK_SIZE));
RGB = label2rgb(cc);
imshow(RGB), hold on
%# find and display the closest block to each cluster
[~,idx] = min(Dist);
[r c] = ind2sub(ceil(size(I)/BLOCK_SIZE), idx);
for i=1:NUM_CLUSTERS
text(c(i)+2, r(i), num2str(i), 'fontsize',20)
end
plot(c, r, 'k.', 'markersize',30)
legend('Centroids')
The centroids do not correspond to coordinates in the image, but to coordinates in the feature space. There is two ways you can test how well kmeans performed. For both ways, you want to fist associate the points with their closest cluster. You get this information from the first output of kmeans.
(1) You can visualize the clustering result by reducing the 6-dimensional space to 2 or 3-dimensional space and then plotting the differently classified coordinates in different colors.
Assuming that the feature vectors are collected in an array called featureArray, and that you asked for nClusters clusters, you'd do the plot as follows using mdscale to transform the data to, say, 3D space:
%# kmeans clustering
[idx,centroids6D] = kmeans(featureArray,nClusters);
%# find the dissimilarity between features in the array for mdscale.
%# Add the cluster centroids to the points, so that they get transformed by mdscale as well.
%# I assume that you use Euclidean distance.
dissimilarities = pdist([featureArray;centroids6D]);
%# transform onto 3D space
transformedCoords = mdscale(dissimilarities,3);
%# create colormap with nClusters colors
cmap = hsv(nClusters);
%# loop to plot
figure
hold on,
for c = 1:nClusters
%# plot the coordinates
currentIdx = find(idx==c);
plot3(transformedCoords(currentIdx,1),transformedCoords(currentIdx,2),...
transformedCoords(currentIdx,3),'.','Color',cmap(c,:));
%# plot the cluster centroid with a black-edged square
plot3(transformedCoords(1:end-nClusters+c,1),transformedCoords(1:end-nClusters+c,2),...
transformedCoords(1:end-nClusters+c,3),'s','MarkerFaceColor',cmap(c,:),...
MarkerEdgeColor','k');
end
(2) You can, alternatively, create a pseudo-colored image that shows you what part of the image belongs to which cluster
Assuming that you have nRows by nCols blocks, you write
%# kmeans clustering
[idx,centroids6D] = kmeans(featureArray,nClusters);
%# create image
img = reshape(idx,nRows,nCols);
%# create colormap
cmap = hsv(nClusters);
%# show the image and color according to clusters
figure
imshow(img,[])
colormap(cmap)