Creating histograms of a matrix with weights in separate matrix
90 views (last 30 days)
Show older comments
I have a matrix A with n values, and each value has a corresponding weight in matrix B. How do I create a weighted histogram in this case? I would like to not specify the number of bins, only the binwidth.
Thank you.
Note: There are no repeating values in A, and alos no repeating values in B.
A = randperm(100); % list of values I need a histogram of
B = randperm(100); % weights for every value in A
h = hist(A)
h.BinWidth = 10;
2 Comments
Answers (2)
Shubham
on 1 Jun 2023
Hi Ana,
Here's how you can create a weighted histogram of matrix A using matrix B, without specifying the number of bins, only the binwidth:
A = randperm(100); % list of values I need a histogram of
B = randperm(100); % weights for every value in A
binwidth = 10; % specify the binwidth
% Determine the edges of the bins based on the data and the binwidth
maxval = max(A);
minval = min(A);
binEdges = minval:binwidth:maxval;
% Create an empty vector to hold the values
numBins = numel(binEdges) - 1;
values = zeros(numBins, 1);
% Calculate the weighted counts for each bin
for i = 1:numBins
idx = A >= binEdges(i) & A < binEdges(i+1);
values(i) = sum(B(idx));
end
% Create a histogram plot with the calculated weighted counts
histogram('BinEdges', binEdges, 'BinCounts', values, 'Normalization', 'probability');
% Set x-axis label and title
xlabel('Value');
ylabel('Frequency');
title('Weighted Histogram of A with Binwidth 10');
In this code, we first determine the edges of the bins based on the minimum and maximum values in A and the specified binwidth. We then calculate the number of bins based on the number of edges. We create an empty vector to hold the weighted counts for each bin. Then, we loop over each bin and calculate the weighted count for that bin by finding the indices of the values that fall within the bin, and summing up the corresponding weights. Finally, we create a histogram using the histogram function and specifying the bin edges and calculated weighted counts. We set the Normalization option to 'probability' to create a probability density function. Finally, we set the x-axis label and title.
0 Comments
J. Alex Lee
on 5 Jul 2024
Edited: J. Alex Lee
on 6 Jul 2024
I know this is old, but wanted to provide another answer based on another relevant Matlab Answers post in case anyone else may be helped by this.
In https://www.mathworks.com/matlabcentral/answers/81805-how-to-make-a-weighted-histogram-with-specific-bins, the accepted answer for a similar problem uses histc and accumarray() to achieve the same outcome as the loop in Shubham's 2023/06/01 answer of this question.
The solution below uses discretize and accumarray().
Caveat that accumarray's sum is slightly different from manual summing...not sure why, assuming its just some kind of precision thing with underlying algorithm for accumarray.
szData = [5000,5000] % dimensions of data set
MaxVal = 17 % max value of fake data generated by randi
% generate some fake data
% rng("default")
data = randi(MaxVal,szData)-0.5; % fix it so bin edges are simple to think about
wgts = rand(szData);
% Define bins
BinEdges = 0:MaxVal;
numBins = numel(BinEdges) - 1;
% method with accumarray
tic
ind = discretize(data(:),BinEdges);
wHistC = accumarray(ind(:),wgts(:));
tC = toc;
% method Shubham 2023
wHistA = zeros(numBins,1);
tic
for i = 1:numBins
idx = data >= BinEdges(i) & data < BinEdges(i+1);
wHistA(i) = sum(wgts(idx));
end
tA = toc;
% method using histcounts
wHistB = zeros(numBins,1);
tic
ind = discretize(data(:),BinEdges);
for k = 1:numBins
wHistB(k) = sum(wgts(ind==k));
end
tB = toc;
tA
tB
tC
diffAB = sum(abs(wHistA - wHistB))
diffAC = sum(abs(wHistA - wHistC))
diffBB = sum(abs(wHistB - wHistC))
0 Comments
See Also
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!