I have 20 numerical data points with x and y coordinates. I would like to plot them in a 2D plot. They will be concentrated around an x and y coordinate. To better visualise this behaviour, I would like to add histogram bars on top of the 2D scatter plot for the x axis, and histogram bars on the right of the 2D plot for the y axis this way, they do not interfere with the axis labels. Now, my 20 numerical points are in fact two sets of 10 and I would like to have both sets plotted in different colours. Something like this:
python plot
How can I do this?
Update:
FWHM11Avg = [3.88,3.43,3.16,3.22,3.73,2.43,2.88,3.01,3.59,2.17];
FWHM11Med = [4.4,3.1,3,3.15,3.9,2,3.00,2.85,3.85,2.2];
FWHM12Avg = [3.50,2.30,2.97,2.97,2.98,2.28,2.94,2.36,3.51,1.7];
FWHM12Med = [3.3,2.1,2.9,2.8,2.9,2.1,2.8,2.30,3.5,1.7];
minx = min([FWHM11Avg; FWHM11Med]);
maxx = max([FWHM11Avg; FWHM11Med]);
miny = min([FWHM12Avg; FWHM12Med]);
maxy = max([FWHM12Avg; FWHM12Med]);
% make figure
figure(1)
clf
% first subplot -- y-data histc
ah1 = subplot(2, 2, 1);
y_bins = 1.5:.25:4.5;
n = hist(FWHM12Avg, y_bins);
bar(y_bins, n, 'vertical', 'on')
hold on
hist(FWHM12Med, y_bins)
bar(y_bins, n, 'vertical', 'on')
% x-data histc
ah2 = subplot(2, 2, 4);
x_bins = 1.5:.25:4.5;
n = hist(FWHM11Avg, x_bins);
bar(x_bins, n, 'horizontal', 'on')
hold on
n = hist(FWHM11Med, x_bins);
bar(x_bins, n, 'horizontal', 'on')
% scatterplot
ah3 = subplot(2, 2, 2);
hold on
scatter(FWHM11Avg, FWHM11Med)
scatter(FWHM12Avg, FWHM12Med)
% link axes, adjust histc orientation
linkaxes([ah1, ah3], 'y')
linkaxes([ah3, ah2], 'x')
set(ah3,'XLim',[minx, maxx]);
set(ah3,'YLim',[miny, maxy]);
ah1.Box = 'off';
ah1.View = [180, -90];
ah1.Visible = 'off';
ah2.Visible = 'off';
ah2.Box = 'off';
ah2.View = [0, -90];
Also there seems not to be an option available for adding numerical axes to the histograms to see how many points there are in a bar - at least in the documentation I did not see any option. Is that so?
Second Update with applied suggestions to the above syntax:
FWHM11Avg = [3.88,3.43,3.16,3.22,3.73,2.43,2.88,3.01,3.59,2.17];
FWHM11Med = [4.4,3.1,3,3.15,3.9,2,3.00,2.85,3.85,2.2];
FWHM12Avg = [3.50,2.30,2.97,2.97,2.98,2.28,2.94,2.36,3.51,1.7];
FWHM12Med = [3.3,2.1,2.9,2.8,2.9,2.1,2.8,2.30,3.5,1.7];
minx = min([FWHM11Avg; FWHM11Med]);
maxx = max([FWHM11Avg; FWHM11Med]);
miny = min([FWHM12Avg; FWHM12Med]);
maxy = max([FWHM12Avg; FWHM12Med]);
% make figure
figure(1)
clf
% first subplot -- y-data histc
ah1 = subplot(2, 2, 1);
y_bins = 1.5:.25:4.5;
n = hist(FWHM12Avg, y_bins);
bar(y_bins, n, 'vertical', 'on')
hold on
hist(FWHM12Med, y_bins)
bar(y_bins, n, 'vertical', 'on')
% x-data histc
ah2 = subplot(2, 2, 4);
x_bins = 1.5:.25:4.5;
n = hist(FWHM11Avg, x_bins);
bar(x_bins, n, 'horizontal', 'on')
hold on
n = hist(FWHM11Med, x_bins);
bar(x_bins, n, 'horizontal', 'on')
% scatterplot
ah3 = subplot(2, 2, 2);
hold on
scatter(FWHM11Avg, FWHM11Med)
scatter(FWHM12Avg, FWHM12Med)
% link axes, adjust histc orientation
linkaxes([ah1, ah3], 'y')
linkaxes([ah3, ah2], 'x')
set(ah3,'XLim',[minx, maxx]);
set(ah3,'YLim',[miny, maxy]);
set(ah1,'Box','off');
set(ah1,'View',[180, -90]);
set(ah1,'Visible','off');
set(ah2,'Visible','off');
set(ah2,'Box','off');
set(ah2,'View',[0, -90]);
Please research before asking. There is a function in Matlab scatterhist which does this
x0 = 6.1;
y0 = 3.2;
n = 50;
r = rand(n ,1 );
theta = 2*pi*rand(n, 1);
x = x0 + r.*cos(theta);
y = y0 + r.*sin(theta);
scatterhist(x,y, 'Direction','out', 'Location', 'NorthEast')
Edit: Using the data you provided. Is this what you want?
FWHM11Avg = [3.88,3.43,3.16,3.22,3.73,2.43,2.88,3.01,3.59,2.17];
FWHM11Med = [4.4,3.1,3,3.15,3.9,2,3.00,2.85,3.85,2.2];
FWHM12Avg = [3.50,2.30,2.97,2.97,2.98,2.28,2.94,2.36,3.51,1.7];
FWHM12Med = [3.3,2.1,2.9,2.8,2.9,2.1,2.8,2.30,3.5,1.7];
% make figure
figure(1)
clf
FWHM11Avg = FWHM11Avg(:);
FWHM11Med = FWHM11Med(:);
FWHM12Avg = FWHM12Avg(:);
FWHM12Med = FWHM12Med(:);
minX = min([FWHM11Avg; FWHM12Avg]);
maxX = max([FWHM11Avg; FWHM12Avg]);
minY = min([FWHM11Med; FWHM12Med]);
maxY = max([FWHM11Med; FWHM12Med]);
resX = 0.25;
resY = 0.25;
nBinsX = ceil((maxX - minX) / resX);
nBinsY = ceil((maxY - minY) / resY);
label = vertcat( ...
num2cell(repmat('FWHM11', size(FWHM11Avg)),2), ...
num2cell(repmat('FWHM12', size(FWHM11Avg)),2));
Avg = vertcat(FWHM11Avg, FWHM12Avg);
Med = vertcat(FWHM11Med, FWHM12Med);
% scatterplot
scatterhist(Avg, Med, 'Group', label, 'Direction','out', ...
'Location', 'NorthEast', 'NBins', [nBinsX, nBinsY])
This is something I've been using lately:
% generate some random data
mu = [1 2];
sigma = [1 0.5; 0.5 2];
R = chol(sigma);
my_data1 = repmat(mu,100,1) + randn(100,2)*R;
mu = [2 1];
sigma = [3 -0.5; -0.5 2];
R = chol(sigma);
my_data2 = repmat(mu,100,1) + randn(100,2)*R;
% find limits
minx = min([my_data1(:, 1); my_data2(:, 1)]);
maxx = max([my_data1(:, 1); my_data2(:, 1)]);
miny = min([my_data1(:, 2); my_data2(:, 2)]);
maxy = max([my_data1(:, 2); my_data2(:, 2)]);
% make figure
figure(1)
clf
% first subplot -- y-data histogram
ah1 = subplot(2, 2, 1);
histogram(my_data1(:, 2), 'Orientation','horizontal', 'Normalization', 'probability', 'BinWidth', 0.5)
hold on
histogram(my_data2(:, 2), 'Orientation','horizontal', 'Normalization', 'probability', 'BinWidth', 0.5)
% x-data histogram
ah2 = subplot(2, 2, 4);
histogram(my_data1(:, 1), 'Normalization', 'probability', 'BinWidth', 0.5)
hold on
histogram(my_data2(:, 1), 'Normalization', 'probability', 'BinWidth', 0.5)
% scatterplot
ah3 = subplot(2, 2, 2);
hold on
scatter(my_data1(:, 1), my_data1(:, 2))
scatter(my_data2(:, 1), my_data2(:, 2))
% link axes, adjust histogram orientation
linkaxes([ah1, ah3], 'y')
linkaxes([ah3, ah2], 'x')
ah3.XLim = [minx, maxx];
ah3.YLim = [miny, maxy];
ah1.Box = 'off';
ah1.View = [180, -90];
ah1.Visible = 'off';
ah2.Visible = 'off';
ah2.Box = 'off';
ah2.View = [0, -90];
producing this plot
This code assumes a recent version of MATLAB (I use 2014b), but can be easily adapted using the old histogram functions (hist, histc) and the set(..) syntax for graphical objects.
I am trying to produce a contour plot for the 3D vectors returned by a custom function in the xy plane where z = 0.
I tried this but I just get an empty graph:
% Stand in for the real function I want to plot.
f = #(x, y, z) [x ^ 2, y ^ 2, x * y + z];
x = linspace(-5, 5, 50);
y = linspace(-5, 5, 50);
z = zeros(length(x), length(y), 3);
% I know this can be vectorized but the function I really want to graph can't
% be.
for i = 1:length(x)
for j = 1:length(y)
z(i, j, :) = f(x(i), y(j), 0);
end
end
figure;
axis equal;
contour(x, y, z);
You should mention what your axis will be. You have x,y and 3 outputs from f.
If you consider 3 outputs of your f as the ones to be plotted then you should use,
contour(z(:,:,1),z(:,:,2),z(:,:,3));
Which will give you this,
I think what you are looking for, is a function with one output, like,
f = #(x, y,z) [x ^ 2 + y ^ 2 + x * y + z ];
x = linspace(-5, 5, 50);
y = linspace(-5, 5, 50);
z = zeros(length(x), length(y));
for i = 1:length(x)
for j = 1:length(y)
z(i, j) = f(x(i), y(j),0);
end
end
contour(x,y,z,20);
I just wondering how to plot a hyperplane of the SVM results.
For example, here we are using two features, we can plot the decision boundary in 2D. But if how can we plot a hyperplane in 3D if we use 3 features?
load fisheriris;
features = meas(1:100,:);
featureSelcted = features(1:100,1:2); % For example, featureSelcted = features(1:100,1:3) can not be plotted
groundTruthGroup = species(1:100);
svmStruct = svmtrain(featureSelcted, groundTruthGroup, ...
'Kernel_Function', 'rbf', 'boxconstraint', Inf, 'showplot', true, 'Method', 'QP');
svmClassified = svmclassify(svmStruct,featureSelcted,'showplot',true);
A similar solution in R can be found at svm-fit-hyperplane, but a Matlab implementation would be handy.
Here is a function to plot 3D SVM results in MATLAB.
function [] = svm_3d_matlab_vis(svmStruct,Xdata,group)
sv = svmStruct.SupportVectors;
alphaHat = svmStruct.Alpha;
bias = svmStruct.Bias;
kfun = svmStruct.KernelFunction;
kfunargs = svmStruct.KernelFunctionArgs;
sh = svmStruct.ScaleData.shift; % shift vector
scalef = svmStruct.ScaleData.scaleFactor; % scale vector
group = group(~any(isnan(Xdata),2));
Xdata =Xdata(~any(isnan(Xdata),2),:); % remove rows with NaN
% scale and shift data
Xdata1 = repmat(scalef,size(Xdata,1),1).*(Xdata+repmat(sh,size(Xdata,1),1));
k = 50;
cubeXMin = min(Xdata1(:,1));
cubeYMin = min(Xdata1(:,2));
cubeZMin = min(Xdata1(:,3));
cubeXMax = max(Xdata1(:,1));
cubeYMax = max(Xdata1(:,2));
cubeZMax = max(Xdata1(:,3));
stepx = (cubeXMax-cubeXMin)/(k-1);
stepy = (cubeYMax-cubeYMin)/(k-1);
stepz = (cubeZMax-cubeZMin)/(k-1);
[x, y, z] = meshgrid(cubeXMin:stepx:cubeXMax,cubeYMin:stepy:cubeYMax,cubeZMin:stepz:cubeZMax);
mm = size(x);
x = x(:);
y = y(:);
z = z(:);
f = (feval(kfun,sv,[x y z],kfunargs{:})'*alphaHat(:)) + bias;
t = strcmp(group, group{1});
% unscale and unshift data
Xdata1 =(Xdata1./repmat(scalef,size(Xdata,1),1)) - repmat(sh,size(Xdata,1),1);
x =(x./repmat(scalef(1),size(x,1),1)) - repmat(sh(1),size(x,1),1);
y =(y./repmat(scalef(2),size(y,1),1)) - repmat(sh(2),size(y,1),1);
z =(z./repmat(scalef(3),size(z,1),1)) - repmat(sh(3),size(z,1),1);
figure
plot3(Xdata1(t, 1), Xdata1(t, 2), Xdata1(t, 3), 'b.');
hold on
plot3(Xdata1(~t, 1), Xdata1(~t, 2), Xdata1(~t, 3), 'r.');
hold on
% load unscaled support vectors for plotting
sv = svmStruct.SupportVectorIndices;
sv = [Xdata1(sv, :)];
plot3(sv(:, 1), sv(:, 2), sv(:, 3), 'go');
legend(group{1},group{end},'support vectors')
x0 = reshape(x, mm);
y0 = reshape(y, mm);
z0 = reshape(z, mm);
v0 = reshape(f, mm);
[faces,verts,colors] = isosurface(x0, y0, z0, v0, 0, x0);
patch('Vertices', verts, 'Faces', faces, 'FaceColor','k','edgecolor', 'none', 'FaceAlpha', 0.5);
grid on
box on
view(3)
hold off
end
Example plot:
% load data
load fisheriris;
% train svm using three features for two species
svmStruct = svmtrain(meas(1:100,1:3),species(1:100),'showplot','false','kernel_function','rbf',...
'boxconstraint',1,'kktviolationlevel',0.05,'tolkkt',5e-3);
% run function described above
svm_3d_matlab_vis(svmStruct,meas(1:100,1:3),species(1:100))