Matlab scatter and histogram plot

2.5k views Asked by At

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]);
2

There are 2 answers

1
user1543042 On

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])
5
zeeMonkeez On

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 marginal histograms 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.