Search code examples
matlabpixel-density

how to create a 3d spatial density map?


I have a time-dependent system of varying number of particles (~100k particles). In fact, each particle represents an interaction in a 3D space with a particular strength. Thus, each particle has (X,Y,Z;w) which is the coordinate plus a weight factor between 0 and 1, showing the strength of interaction in that coordinate. Here http://pho.to/9Ztti I have uploaded 10 real-time snapshots of the system, with particles are represented as reddish small dots; the redder the dot, the stronger the interaction is.

The question is: how one can produce a 3D (spatial) density map of these particles, preferably in Matlab or Origin Pro 9 or ImageJ? Is there a way to, say, take the average of these images based on the red-color intensity in ImageJ?

Since I have the numerical data for particles (X,Y,Z;w) I can analyze those data in other software as well. So, you are welcome to suggest any other analytical approach/software

Any ideas/comments are welcome!


Solution

  • Assuming your data is in 3D continuous space and your dataset is just a list of the 3d positions of each particle interaction, it sounds like you want to make a 4D weighted histogram. You'll have to chop the 3d space into bins and sum the weighted points in each bin over time, then plot the results in a single 3d plot where color represents the summed weighted interactions over time.

    Heres an example with randomly generated particle interactions:`

    %% Create dataSet of random particle interations in 3d space
    for i=1:5000
        if i == 1
            dataSet = [rand()*100 rand()*100 rand()*100 rand() i];
        else
            dataSet(i,:) = [rand()*100 rand()*100 rand()*100 rand() i];
        end
    end
    % dataSet = [x y z interactionStrength imageNumber]
    
    xLimits = [min(dataSet(:,1)) max(dataSet(:,1))];
    yLimits = [min(dataSet(:,2)) max(dataSet(:,2))];
    zLimits = [min(dataSet(:,3)) max(dataSet(:,3))];
    
    binSize = 10; % Number of bins to split each spatial dimention into
    binXInterval = (xLimits(2)-xLimits(1))/binSize;
    binYInterval = (yLimits(2)-yLimits(1))/binSize;
    binZInterval = (zLimits(2)-zLimits(1))/binSize;
    
    histo = [];
    for i=xLimits(1)+(binSize/2):binXInterval:xLimits(2) + (binSize/2)
        for j=yLimits(1)+(binSize/2):binYInterval:yLimits(2) + (binSize/2)
            for k=zLimits(1)+(binSize/2):binZInterval:zLimits(2) + (binSize/2)
                %% Filter out particle interactions found within the current spatial bin
                idx = find((dataSet(:,1) > (i - binSize)) .* (dataSet(:,1) < i));
                temp = dataSet(idx,:);
                idx = find((temp(:,2) > (j - binSize)) .* (temp(:,2) < j));
                temp = temp(idx,:);
                idx = find((temp(:,3) > (k - binSize)) .* (temp(:,3) < k));
                temp = temp(idx,:);
                %% Add up all interaction strengths found within this bin
                histo = [histo; i j k sum(temp(:,4))];
            end
        end
    end
    %% Remove bins with no particle interactions
    idx = find(histo(:,4)>0);
    histo = histo(idx,:);
    numberOfImages = max(dataSet(:,5));
    %% Plot result
    PointSizeMultiplier = 100000;
    scatter3(histo(:,1).*binXInterval + xLimits(1),histo(:,2).*binYInterval + yLimits(1),histo(:,3).*binZInterval + zLimits(1),(histo(:,4)/numberOfImages)*PointSizeMultiplier,(histo(:,4)/numberOfImages));
    colormap hot;
    %Size and color represent the average interaction intensity over time
    

    4D histogram made from 10000 randomly generated particle interactions. Each axis divided into 10 bins. Size and color represent summed particle interactions in each bin over time: enter image description here