3D Histogram from raw data

97 ビュー (過去 30 日間)
Biraj Khanal
Biraj Khanal 2023 年 5 月 17 日
コメント済み: Biraj Khanal 2023 年 5 月 24 日
I am trying to create the a rainflow matrix out of time history of a load data. I can do it easily with the rainflow command but I am trying to learn how I can produce it myself. It is basically a 3D Histogram of three variables ( Mean, Range and Cycle count , random X,Y and Z let's say )
This is what a rainflow matrix looks like for reference.
For any dataset with X,Y and Z data, I undertand that the first step is to discretize X and Y . What I do not understand is how I can allot the Z value to each bins and ultimately plot something like this.

回答 (1 件)

Mathieu NOE
Mathieu NOE 2023 年 5 月 17 日
hello
see example below - this is equivalent to hist3
% dummy data (col vectors)
x = rand(100,1);
y = rand(100,1);
z = rand(100,1);
%% bin the data (Hist3 clone)
nBins = 10; %number of bins (there will be nBins + 1 edges)
XEdge = linspace(min(x),max(x),nBins+1);
YEdge = linspace(min(y),max(y),nBins+1);
[~, xBin] = histc(x, XEdge);
[~, yBin] = histc(y, YEdge);
% count number of elements per (x,y) pair
[xIdx, yIdx] = meshgrid(1:nBins, 1:nBins);
xyPairs = [xIdx(:), yIdx(:)];
Z = zeros(size(xyPairs,1),1);
for i = 1:size(xyPairs,1)
Z(i) = sum(ismember([xBin, yBin], xyPairs(i,:), 'rows'));
end
% Reshape nPerBin to grid size
Z = reshape(Z, [nBins, nBins]);
% plot data
figure(1)
b = bar3(Z);
% change bar color to match Z value
for k = 1:length(b)
zdata = b(k).ZData;
b(k).CData = zdata;
b(k).FaceColor = 'interp';
end
colorbar('vert');
% Change colormap
colormap jet
% Label the axes
xlabel('x')
ylabel('y')
title('hist3 simulation');
  2 件のコメント
Biraj Khanal
Biraj Khanal 2023 年 5 月 19 日
編集済み: Biraj Khanal 2023 年 5 月 19 日
Hi Mathieu , this was really helpful to get started. I replaced the histc with histcounts ( which I believe is the same thing) . However, what you have done is basically counted the xy pairs in each bins and presented Z axis as the count. Note that you have not used the initial z data at all. What I am doing is trying to put those respective z data (because the data is a x,y,z pair) in each bin and make a sum of them to present as Z of the final histogram. I have done that changing a line of your code. Check the for loop.
%dummy data (col vectors)
x = rand(100,1);
y = rand(100,1);
z = rand(100,1);
%% bin the data (Hist3 clone)
nBins = 10; %number of bins (there will be nBins + 1 edges)
% XEdge = linspace(min(x),max(x),nBins+1);
% YEdge = linspace(min(y),max(y),nBins+1);
% [~, xBin] = histc(x, XEdge);
% [~, yBin] = histc(y, YEdge);
[~,XEdge,XBin] = histcounts(x,nBins);
[~,YEdge,YBin] = histcounts(y,nBins);
[xIdx, yIdx] = meshgrid(1:nBins, 1:nBins);
xyPairs = [xIdx(:), yIdx(:)];
Z = zeros(size(xyPairs,1),1);
for i = 1:size(xyPairs,1)
%Z(i) = sum(ismember([xBin, yBin], xyPairs(i,:), 'rows'));
z_idx = find(ismember([XBin, YBin], xyPairs(i,:), 'rows'));
Z(i) = sum(z(z_idx));
end
Z = reshape(Z, [nBins, nBins]);
%Z = flip(Z,1);
% plot data
figure(1)
b = bar3(Z);
% change bar color to match Z value
for k = 1:length(b)
zdata = b(k).ZData;
b(k).CData = zdata;
b(k).FaceColor = 'interp';
end
colorbar('vert');
% Change colormap
colormap jet
% Label the axes
xlabel('x')
ylabel('y')
title('hist3 simulation');
Now, there are couple of more things that I am trying to do:
  1. As you can see, the mesh in XY is not as we generally liike to see, The Y bins should be flipped. If only for the sake of Z, I could just flip Z. But I believe there is a better way to arrange this.
  2. Instead of the bin index, I want to see the edges so that the histogram is relatable to the original data.
Do you have some suggestion?
Biraj Khanal
Biraj Khanal 2023 年 5 月 24 日
For anyone having similar problem, here is what I did to address the issues in my comment above :
Z = flip(Z,1); %flips the bar graph
ylim([0 nBins+1 ]); % to make the grid well viyible
xlim([0 nBins+1]);
tick_num = 5; %set the number of ticks on x and y axis
x = 0: nBins/tick_num : nBins ; x = x+0.4 ; x(1) =0.6; %first bin is plotted from x = 0.6 , each bin ends at edge+0.4
y = x;
xticks(x)
yticks(y)
xticklabels([XEdge(1: nBins/tick_num :end)]);
yticklabels(flip([YEdge(1: nBins/tick_num :end)]));
If anyone can suggest simpler way to go about this, it would be great!!

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeData Distribution Plots についてさらに検索

製品


リリース

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by