How to create 3D joint density plot MATLAB?

2020-03-07 23:40发布

问题:

I 'm having a problem with creating a joint density function from data. What I have is queue sizes from a stock as two vectors saved as:

X = [askQueueSize bidQueueSize];

I then use the hist3-function to create a 3D histogram. This is what I get: http://dl.dropbox.com/u/709705/hist-plot.png

What I want is to have the Z-axis normalized so that it goes from [0 1].

How do I do that? Or do someone have a great joint density matlab function on stock?

This is similar (How to draw probability density function in MatLab?) but in 2D.

What I want is 3D with x:ask queue, y:bid queue, z:probability.

Would greatly appreciate if someone could help me with this, because I've hit a wall over here.

回答1:

I couldn't see a simple way of doing this. You can get the histogram counts back from hist3 using

[N C] = hist3(X);

and the idea would be to normalise them with:

N = N / sum(N(:));

but I can't find a nice way to plot them back to a histogram afterwards (You can use bar3(N), but I think the axes labels will need to be set manually).

The solution I ended up with involves modifying the code of hist3. If you have access to this (edit hist3) then this may work for you, but I'm not really sure what the legal situation is (you need a licence for the statistics toolbox, if you copy hist3 and modify it yourself, this is probably not legal).

Anyway, I found the place where the data is being prepared for a surf plot. There are 3 matrices corresponding to x, y, and z. Just before the contents of the z matrix were calculated (line 256), I inserted:

n = n / sum(n(:));

which normalises the count matrix.

Finally once the histogram is plotted, you can set the axis limits with:

xlim([0, 1]);

if necessary.



回答2:

With help from a guy at mathworks forum, this is the great solution I ended up with:

(data_x and data_y are values, which you want to calculate at hist3)

x = min_x:step:max_x; % axis x, which you want to see
y = min_y:step:max_y; % axis y, which you want to see

[X,Y] = meshgrid(x,y); *%important for "surf" - makes defined grid*

pdf = hist3([data_x , data_y],{x y}); %standard hist3 (calculated for yours axis)
pdf_normalize = (pdf'./length(data_x)); %normalization means devide it by length of 
                                         %data_x (or data_y)
figure()
surf(X,Y,pdf_normalize) % plot distribution

This gave me the joint density plot in 3D. Which can be checked by calculating the integral over the surface with:

integralOverDensityPlot = sum(trapz(pdf_normalize));

When the variable step goes to zero the variable integralOverDensityPlot goes to 1.0

Hope this help someone!



回答3:

There is a fast way how to do this with hist3 function:

[bins centers] = hist3(X); % X should be matrix with two columns
c_1 = centers{1};
c_2 = centers{2};
pdf = bins / (sum(sum(bins))*(c_1(2)-c_1(1)) * (c_2(2)-c_2(1)));

If you "integrate" this you will get 1.

sum(sum(pdf * (c_1(2)-c_1(1)) * (c_2(2)-c_2(1))))