Anybody help me by providing MatLab code for the three-dimensional histograms.
Show older comments
I have three-dimensional data such as X=(100*1) , Y=(100*1) , Z=(100*1). I want to display three dimensional histograms for the (100*3).
Please help me.
4 Comments
KSSV
on 5 Aug 2021
Walter Roberson
on 5 Aug 2021
You have 3 input variables, X, Y, Z. You are calculating a count for each voxel (it is not clear how many bins in each dimension of what edges should be used). The result is going to have 3 independent variables and one dependent variable, which requires a 4D plot not a 3d plot.
sharmin sathi
on 5 Aug 2021
sharmin sathi
on 13 Dec 2021
Edited: sharmin sathi
on 14 Dec 2021
Answers (4)
Walter Roberson
on 15 Dec 2021
0 votes
Sorry, No, I do not know how to draw 4 dimensional histograms.
You can quantize the X, Y, and Z coordinates, and you can count the number of entries per voxel, and you could do that independent for each of the categories. You could end up with a 3D array of counts for each of the 4 categorize. But in order to draw a histogram, you need an extra dimension. A histogram of 1D data requires two spatial dimensions to draw (X = category, Y = count). A histogram of 2D data requries three spatial dimensions to draw (X = first category, Y = second category, Z = count). A histogram of 3D data would require four spatial dimensions to draw (X, Y, Z, count).
Unfortunately, hardware that is able to draw in 4 spatial dimensions is extremely rare. So rare that I have never heard of any. The limit I have ever heard of was equipment that could, to a limited extent, work in 3 spatial dimensions and animate over time (but it was not able to handle holes.)
If you have three spatial dimensions and a value at each location, then there are some things you can do with representing different values by different colors and using volume rendering with some transparency. These are not histograms, though.
2 Comments
sharmin sathi
on 17 Dec 2021
Edited: sharmin sathi
on 17 Dec 2021
Walter Roberson
on 17 Dec 2021
You cannot draw a histogram of 3D data unless you have an output device which is able to operate in 4 spatial dimensions (something not known to exist), or else you allow one of the spatial dimensions to be represented by time.
Image Analyst
on 15 Dec 2021
With the poster's "X=(100*1) , Y=(100*1) , Z=(100*1)" you can get a 3-D histogram. Or you can get 3 1-D histograms. Or you can get a 3-D histogram like this:
h3 = zeros(length(X), length(Y), length(Y));
for k = 1 : length(X)
% Increment count by 1.
h3(X(k), Y(k), Z(k)) = h3(X(k), Y(k), Z(k)) + 1;
end
assuming the values of X, Y, and Z were already bin numbers. Otherwise you'd have to convert them to bin numbers using rescale() and round().
What you want to do really depends on what you want. What are you going to do with this/these histograms?
6 Comments
sharmin sathi
on 17 Dec 2021
Image Analyst
on 17 Dec 2021
Try this:
fileName = 'data_with_group.csv';
data = readmatrix(fileName)
X = data(:, 1);
Y = data(:, 2);
Z = data(:, 3);
% Rescale data so there are 100 bins for each.
numBins = 10;
binsX = round(rescale(X, 1, numBins));
binsY = round(rescale(X, 1, numBins));
binsZ = round(rescale(X, 1, numBins));
h3 = zeros(numBins, numBins, numBins);
for k = 1 : length(X)
% Increment count by 1.
h3(binsX(k), binsY(k), binsZ(k)) = h3(binsX(k), binsY(k), binsZ(k)) + 1;
end
h3
sharmin sathi
on 17 Dec 2021
Edited: sharmin sathi
on 17 Dec 2021
Voss
on 17 Dec 2021
@sharmin sathi Maybe it would be helpful if you can find (or draw) and share a picture of a histogram with 3 independent variables, like how you envision it.
As @Walter Roberson points out, any histogram requires one more dimension than the number of independent variables it is depicting. Since you wish to make a histogram of 3 independent variables, this means the required histogram must be 4-dimensional. As far as I know, there are no built-in MATLAB functions for visualizing data in more than 3 dimensions. I think the closest you could get is to use time as one of the dimensions and make an animation or video (that is, a time-varying 3-dimensional visualization). Is this what you have in mind?
Walter Roberson
on 17 Dec 2021
You have a 10 x 10 x 10 array of values. That is a cube of values.
You want to represent each value by a height. That is inherent in histogram: a histogram represents different counts by different heights.
So you have a cube of values, and at each location in the cube, you want a height.
Those heights would have to point in a 4th direction. However, no-one knows how to extend into a 4th spatial dimension. Scientists are not even sure if a 4th spatial dimension exists (but some parts of physics are a lot easier to explain if at least one more spatial dimension exists.)
Image Analyst
on 17 Dec 2021
Prepare to have your mind blown:
@sharmin sathi, like we've said before you can visualize a 4-D histogram by changing the size and/or color of the markers using scatter3.
sharmin sathi
on 20 Dec 2021
0 votes
2 Comments
sharmin sathi
on 28 Dec 2021
Edited: Walter Roberson
on 28 Dec 2021
Walter Roberson
on 28 Dec 2021
You cannot pass x, y, z values to bar3(). Your z values are being interpreted as bar width and your x values are being intepreted as y and your y values are being interpreted as z.
I am having trouble getting the coloring working, but this is what I have so far.
This code voxelizes the data (which is something histograms have to do). It draws in each occupied voxel.
For each voxel, it figures out which group has the greatest number of points within the voxel. It tries to color the voxel according to that label. The calculation of which label to use appears to be correct for the voxels, but I am having difficulty in getting patch to display anything other than black faces.
filename = 'https://www.mathworks.com/matlabcentral/answers/uploaded_files/845690/data_with_group.csv';
labelcolors = [
0 0 1
0 1 0
0 1 1
1 0 0]; %must be rgb
data = readmatrix(filename);
x = data(:, 1);
y = data(:, 2);
z = data(:, 3);
label = data(:,4);
[groups, ID] = findgroups(label);
ngroups = length(ID);
if ngroups > size(labelcolors,1)
error('too many groups, provide more labelcolors');
end
Nx = 20; Ny = 20; Nz = 20;
xvox = (max(x)-min(x))/(Nx-1);
yvox = (max(y)-min(y))/(Ny-1);
zvox = (max(z)-min(z))/(Nz-1);
xidx = floor(x/xvox); xbin = xidx - min(xidx) + 1;
yidx = floor(y/yvox); ybin = yidx - min(yidx) + 1;
zidx = floor(z/zvox); zbin = zidx - min(zidx) + 1;
xq = xidx * xvox; yq = yidx * yvox; zq = zidx * zvox;
counts = accumarray([ybin(:), xbin(:), zbin(:)], 1, [Ny Nx Nz]);
occupied = counts > 0;
oind = find(occupied);
gcounts = cell(ngroups, 1);
for K = 1 : ngroups
mask = groups == K;
gcounts{K} = accumarray([ybin(mask), xbin(mask), zbin(mask)], 1, [Ny Nx Nz]);
end
gcounts4 = cat(4, gcounts{:});
[~, biggestgroupidx] = max(gcounts4, [], 4);
colidx = biggestgroupidx(occupied);
[ox, oy, oz] = ind2sub(size(occupied), oind);
oxq = (ox + min(xidx) - 1) * xvox;
oyq = (oy + min(yidx) - 1) * yvox;
ozq = (oz + min(zidx) - 1) * zvox;
noq = length(oxq);
rF = [1 2 3 4 1; 8 7 6 5 8; 1 4 6 7 1; 2 8 5 3 2; 1 7 8 2 1; 3 5 6 4 3]; %in closed form
rV = [0 0 0; 1 0 0; 1 0 1; 0 0 1; 1 1 1; 0 1 1; 0 1 0; 1 1 0] .* [xvox, yvox, zvox];
%noq = 2;
poxq = oxq(1:noq); poyq = oyq(1:noq); pozq = ozq(1:noq);
allF = repmat(rF(:,1:end-1), noq, 1) + 8*repelem((0:noq-1).', size(rF,1), 1);
allV = repelem([poxq, poyq, pozq], size(rV,1), 1) + repmat(rV, noq, 1);
[mappedV, ~, Vidx] = unique(allV, 'rows');
mappedF = Vidx(allF);
cdata = labelcolors(colidx,:);
p = patch('Faces', mappedF, 'Vertices', mappedV, 'FaceVertexCData', cdata, ...
'LineWidth', 0.1, 'EdgeColor', 'none', 'FaceAlpha', 0.1);
colormap(labelcolors);
xlabel('x'); ylabel('y'); zlabel('z');
view(3)
2 Comments
sharmin sathi
on 29 Dec 2021
Franz-Josef Siegemund
on 3 Mar 2023
I fixed the color issue by doing the following which repeats the elemts for each of the 6 faces of a cube.
cdata = labelcolors(colidx,:);
cdata = repelem(cdata,6,1);
Categories
Find more on Data Distribution Plots in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
