Switching from hist to histogram

I am trying to make my code more robust by switching from use of histogram to hist.
Currently, I use hist as follows:
hist(psd,vec)
where psd is a matrix and vec is a vector.
The output of hist is a matrix where the height is the length of the vec data, and the width is the width of the psd data.
It gives me the values in psd, in bins with bin centres? listed by vec.
The output of histogram is instead an object, and I'm not sure how to derive the info I need from this object? Thanks

 Accepted Answer

dpb
dpb on 10 Nov 2025
Edited: dpb on 10 Nov 2025
The changes in behavior relative to venerable hist introduced by histogram are a pain, agreed. That there isn't an option to specify bin centers instead of only edges is an egregious omission. While one can convert the centers to edges, it's just another piece of minutiae to deal with instead of solving the underlying problem. At least they ought to have packaged a conversion function that implements the conversion outlined at <Convert Bin Centers to Edges>.
As for your usage, "if it ain't broke, don't fix it!" would be my recommendation. While deprecated for new code, there's no chance Mathworks can remove hist entirely and while it might be somewhat advantageous for new code to use the newer function, there really isn't any strong reason to work over current code unless there were some real advantage to the object that is presently difficult later on in your code besides just the shown code snippet usage.
$0.02, im(ns)ho, ymmv, etc., etc., ...

7 Comments

Thanks! Yes - my reason for this post is concern that this function will be removed in the future. Can you please explain how you know that wont be the case?
dpb
dpb on 10 Nov 2025
Edited: dpb on 10 Nov 2025
It's just too ubiquitous and entrenched...the uproar would be deafening.
That is opinion as I am not Mathworks employee and have no inside information source, but I just can't imagine it going away any time even remotely close. It has only been given the "Not recommended" moniker; the "May be removed in a future release" warning hurricane flag has yet to be hoisted and it is generally quite a number of releases before anything actually does happen.
My predeliction would be to put off spending time on it unless I had a very large number of usages that simply had to be maintained no matter what; otherwise there would be time enough to deal with it when it truly became necessary (if that time ever were to come).
I don't recall if I ever formally submitted the enchancement request regarding having a 'BinCenters' option and the builtin conversion function or not; I would recommend filing those just as a complaint; they just might incorporate a more painless way to make the conversion. Of course, it is a "one-time sit down and do it" thing, it's just irritating to waste time doing stuff that really doesn't do anything new or different just to work around a change.
In large part, it depends also on how important/critical it is to maintain the present precise behavior to reproduce identical results. There's where the details of the changes come into play and testing and validation may become the bottleneck, not the actual coding changes. The new version sets the boundary splits on the right instead of left and so the edges computed from the existing center points have to be munged on by an epsilon to move then just a tad to compensate. That may not be a critical point, but if it is necessary to guarantee prior results, it is a complication. That kind of thing is what prevented being able to use MATLAB in former environment for any safety-related calculations because of Mathworks' penchant for changing behavior at will that would require a complete revalidation every release to satisfy NRC licensing. It all depends upon just what requirements you're operating under.
"Of course, it is a "one-time sit down and do it" thing, it's just irritating to waste time doing stuff that really doesn't do anything new or different just to work around a change." - hard agree!
Thanks a lot for your input and considered response. I only use this function for one analysis at the moment but it is a key one and something I will repeat over time. I think I will stick with hist like you said, and hope for the best...
I've really come to appreciate the normalization property of the histogram object.
It's not so much the packaging as that they didn't provide a painless path to be able to reproduce prior behavior. I do find having to only set edges a nuisance as the typical use I have really is based on desired bin centers instead. I haven't yet taken the time to build a generic translation function.
If you have edges and want centers
centers = (edges(1:end-1) + edges(2:end)) / 2; % Centers are the average of the two edge locations.
If you have centers and bin widths and want edges:
numBins = numel(centers);
firstEdge = centers(1) - binWidth/2;
lastEdge = centers(end) + binWidth/2;
edges = linspace(firstEdge, lastEdge, numBins + 1);
dpb
dpb on 12 Nov 2025
Edited: dpb on 12 Nov 2025
Unfortunately, that doesn't quite reproduce what hist does in general...and it also fails for nonuniform binning.
>> x=randn(1000,1);
>> [min(x) max(x)]
ans =
-3.2320 3.5699
>> [n,c]=hist(x,-2:2)
n =
64 241 396 225 74
c =
-2 -1 0 1 2
>> sum(n)
ans =
1000
>>
The bin width is 1 so first edge would be -2.5 and last 2.5 and n=6...
>> e=linspace(-2.5,2.5,6)
e =
-2.5000 -1.5000 -0.5000 0.5000 1.5000 2.5000
>> h=histogram(x,e)
h =
Histogram with properties:
Data: [1000×1 double]
Values: [61 241 396 225 60]
NumBins: 5
BinEdges: [-2.5000 -1.5000 -0.5000 0.5000 1.5000 2.5000]
BinWidth: 1
BinLimits: [-2.5000 2.5000]
Normalization: 'count'
FaceColor: 'auto'
EdgeColor: [0 0 0]
Show all properties
>> h.BinCounts
ans =
61 241 396 225 60
>> sum(h.BinCounts)
ans =
983
>>
One has to mung on the end limits to capture the range.
>> e=e.*[inf ones(1,4) inf];
>> h=histogram(x,e)
h =
Histogram with properties:
Data: [1000×1 double]
Values: [64 241 396 225 74]
NumBins: 5
BinEdges: [-Inf -1.5000 -0.5000 0.5000 1.5000 Inf]
BinWidth: 'nonuniform'
BinLimits: [-Inf Inf]
Normalization: 'count'
FaceColor: 'auto'
EdgeColor: [0 0 0]
Show all properties
>> h.BinCounts
ans =
64 241 396 225 74
>> sum(h.BinCounts)
ans =
1000
>>
Even if the sample happened to not exceed +/-2.5, the count in each bin might be just a little bit different if an observation did happen to fall exactly on the bin edge as one sorts to the left, the other to the right. That's not a likely occurrence with randomly generated data as here, but could be if the data were sampled or rounded with a given precison, for example, and is a more subtle behavior difference. The boundaries are treated differently in substance, however.
One can live with either, but the conversion from one to the other isn't as trivial as Mathworks would have you believe.

Sign in to comment.

More Answers (0)

Products

Release

R2024b

Tags

Asked:

on 10 Nov 2025

Edited:

dpb
on 12 Nov 2025

Community Treasure Hunt

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

Start Hunting!