File Exchange

image thumbnail

Data density plot

version 1.1 (2.45 KB) by Malcolm McLean
Plots data density of a two-dimensional distribution for human viewing.

30 Downloads

Updated 29 Nov 2014

View License

Data density can be hard to read from scatter plots due to overstriking. I therefore calculate data density at each pixel as the reciprocal of the sum of squared distance from each point, adding a fudge factor to prevent points actually within the pixel going to infinity.
The resulting plot allow for a visual fix on data density.

Cite As

Malcolm McLean (2019). Data density plot (https://www.mathworks.com/matlabcentral/fileexchange/31726-data-density-plot), MATLAB Central File Exchange. Retrieved .

Comments and Ratings (17)

Changyong He

I rewrite the function dataDensity after line 22 and vectorise this block (butI do not know its meaning)
len = length(x);
% two different vectorisation
if len>height*width

for ii = 0: height - 1
yi = limits(3) + ii * deltay + deltay/2;
for jj = 0 : width - 1
xi = limits(1) + jj * deltax + deltax/2;
dist2 = (x - xi).^2 + (y - yi).^2;
dmap(ii+1,jj+1) = sum( 1 ./ ( dist2 + fudge));
end
end

else

ii = [0:height-1]';
jj = 0: width-1;

yi = limits(3) + ii * deltay + deltay/2;
xi = limits(1) + jj * deltax + deltax/2;
for i = 1:len
dist2 = (x(i) - xi).^2 + (y(i) - yi).^2;
dmap = dmap + 1 ./ ( dist2 + fudge);
end
end
end

I suggest use hist3 and pcolor to plot density plot.

Sophia Bano

The y-axis can be flipped by using
map = flipdim(map,1);

RAJ DATTA

hello sir, I am a student of 1st yr, geology.I have X,Y and Data values.please, give me an example how to use the data values. My mail ID is : rajnraj100@gmail.com

Thank you

Good idea, but very slow. Otherwise, I would give it 5-star rating.

Alain

For the y axis issue and to write your own ranges along the axes, you may modify the DataDensityPlot function as follows:

function [ f ] = DataDensityPlot( x, y, levels, limits)

map = dataDensity(x, y, 256, 256, limits);
map = map - min(min(map));
map = floor(map ./ max(max(map)) * (levels-1));

f = figure();
image(map);
colormap(jet(levels));

if(nargin == 4)

set(gca, 'XTick', [1 256]); % --
set(gca, 'XTickLabel', [limits(1) limits(2)]); % --
set(gca, 'YTick', [1 256]); % --
set(gca, 'YTickLabel', [limits(3) limits(4)]); % --
set(gca, 'YDir', 'normal'); % --

else

set(gca, 'XTick', [1 256]);
set(gca, 'XTickLabel', [min(x) max(x)]);
set(gca, 'YTick', [1 256]);
set(gca, 'YTickLabel', [min(y) max(y)]);

end

uiwait;

end

---------------------

It may then be called for instance as follows:

limits = [1 4 1 4];
DataDensityPlot(x, y, 100, limits);

---------------------

If you have weights associated to your data points, you can transform your x and y vectors before feeding them to DataDensityPlot function as follows:

function [wx, wy] = WeightedDensityTransform(x, y, weights)

if (isequal(size(x),size(y),size(weights)) == 0)
error('The input vectors must have the same dimensions');
end

sizeX = size(x);
length = sizeX(2);

index=0;

for i=1:1:length

depth = round(weights(i));
index=index+1;
wx(index) = x(i);
wy(index) = y(i);

if (depth > 1)

for j=1:1:depth-1
index = index + 1;
wx(index) = x(i);
wy(index) = y(i);
end;

end;
end;
end

---------------------

You may then call it in the following way:

[wx, wy] = WeightedDensityTransform(x,y, w);
limits = [1 4 1 4];
DataDensityPlot(wx, wy, 100, limits);

Jeremy

Functional, but a bit slow. I wrote a similar function using hist3 to perform the density calculation, runs a million samples in less than a second.

Nina

Great in it does what I want, but I have the same problem with the yaxis reversed and matlab frozen while window open. Is there an improved or similar function?

Ben Ruppel

Great tool, but maybe it should flip the y-axis so the results aren't upside down. Also, Matlab stays frozen in a busy state as long as the result figure is open. Need to close the figure before I can do anything else.

super slow:(

Very slow. Don't replace the kk loop with parfor as bmv suggests, just vectorize the calculation and get rid of the loop:

dmap(ii+1, jj+1) = sum( 1./ ( (x - xi).^2 + (y - yi).^2 + fudge) );

The other loops can be vectorized as well if you use bsxfun.

J G. Yes. Just pass in a dimension of one pixel for the y axis, and it ought to provide you with a data density plot. You'll have to stretch the image to see it.

J G

Good function! Would it work for one-dimensional data, ie. a vector? I am using hist(Y) but would prefer to show the density like this... Thanks!

bmv

Replace this part "for kk = 1: length(x)"
to this:
"parfor kk = 1: length(x)"
This will help speed up the computation for multicore systems after running matlabpool.

Updates

1.1

Toolbox

MATLAB Release Compatibility
Created with R2009b
Compatible with any release
Platform Compatibility
Windows macOS Linux