Creating histograms of a matrix with weights in separate matrix

74 views (last 30 days)
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)
Error using hist
Input arguments must be numeric or a categorical array.
h.BinWidth = 10;
  2 Comments
Ana Lorena Abila
Ana Lorena Abila on 11 May 2023
Hi Vural,
Yes I've seen it and am trying it, but I think I need to set the number of bins - I don't want to set the number of bins myself, just the bin width, and was wondering if there was another way similar to this.
Thank you!

Sign in to comment.

Answers (2)

Shubham
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.

J. Alex Lee
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
szData = 1x2
5000 5000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
MaxVal = 17 % max value of fake data generated by randi
MaxVal = 17
% 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
tA = 0.9758
tB
tB = 1.1477
tC
tC = 0.2623
diffAB = sum(abs(wHistA - wHistB))
diffAB = 0
diffAC = sum(abs(wHistA - wHistC))
diffAC = 2.9139e-07
diffBB = sum(abs(wHistB - wHistC))
diffBB = 2.9139e-07

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!