File Exchange

image thumbnail

Efficient 2D histogram, no toolboxes needed

version (33.1 KB) by Jonathan C. Lansey
Creates 2D histogram of scatterplot or lineseries data, really fast, fully featured.


Updated 16 Sep 2015

View Version History

View License

Displays a 2d histogram for your data, it will set the bins appropriately
NDHIST(x,y); where x and y are equal length vectors. It will choose
reasonable axis bounds and bins to present your data. The
default parameters may leave some data off the chart.
NDHIST(XY); where XY = [x y] and x,y are vectors
NDHIST(z); where z is a vector of complex numbers, (x+1i*y) or amplitude*exp(1i*theta)
NDHIST(y); where y is a vector of real numbers will plot a 2d histogram
of the points, as if it were a line-chart. It is equivalent
to calling ndhist(1:length(y),y);

N = NDHIST(x,y); returns a matrix N containing the counts for each bin
determined by the histogram.
[edgesX2,edgesY2,N] = NDHIST(x,y); which returns a matrix N containing
the counts for each bin determined by the histogram. You can
plot it with sanePColor(edgesX2,edgesY2,N); (from Matlabcentral)

NDHIST(...,'param','value','param','value', ... ); Run ndhist with specific

List of special parameters:

'filter' : This will apply a gaussian filter to the final histogram data.
The default filter width is 5 bins wide. If you pass a number
then that will be used. Even numbered filter parameters will be
changed to odd numbers to keep the filter perfectly symetrical.

'log' : Change the colormap to be on a log scale to represent data
over a large dynamic range.

'bins' : Change the size of the bins. For example '2' will create a
plot with twice the default number of bins; 0.5 will have half
the default number of bins. The default uses Scott's normal
reference rule. Unclear if it is ideal for 2d histograms...
If you are looking for a histogram with specific bins, use the
subfunction hist3. Feel free to implement it as an additional
parameter 'edgdes','edgesx' or 'edgesy'

'binsx' : Change the size of only the x bins. 'fx'
'binsy' : Change the size of only the y bins. 'fy'

axis : This is to set the range of the plot, [xmin xmax ymin ymax]
The default range is set to 3*std(x) and 3*std(y) where the
parameter stdTimes=3 is hard-coded in this version and
potentially added as a parameter in a later version.

max : This is to set the range of the plot to be such that every
point will be contained within the plot.

intbins : Set the bins to be intiger widths. For both x and y

intbinsx : Set the x bins to be intiger widths. 'intx'
intbinsy : Set the y bins to be intiger widths. 'inty'

normalizex: Normalize the plot so that the sum of all the y values in each
x bin sum to one.

normalizey: Normalize the plot so that the sum of all the x values in each
y bin sum to one.

normalizeR: Normalize the plot so that the you can clearly see how the
distribution vary's over angle. It weights points in the outer
radius by the diameter at that radius.

points: Plot the points on top of the colored histogram.

3D: Use a 3D column graph instead of a colored heatmap

radial : Set the axis to be equal and add a polar grid 'r'

'samebins': NOT IMPLEMENTED YET. Would set the width of the x and y bins
to be equal to each other and the axis equal too.

user parameters:
filter: This will filter the data, you may choose to follow it with a
number. This number will represent the radius of the circular
gaussian filter. Other ways to call it: 'filt','filtering','f'


To test the function you may use this example:

If you have amplitude and angle measures then pass this:
z = amp*exp(1i*ang);


% Note
The name of this function comes because really its a 2d hist, but since I
already have an 'nhist' I thought I might name it this.


Cite As

Jonathan C. Lansey (2021). Efficient 2D histogram, no toolboxes needed (, MATLAB Central File Exchange. Retrieved .

Comments and Ratings (29)

Clair Stark


Jeremie Lagarde

Really useful. I found that the tick marks for the x axis disappeared from the 3D plot, which was easily rectified by adding xticks('auto'); after axis('tight'); on line 427.

Marc Vogtmann

Yutian Wen

yurema gonzalez

Hi, great function, many thanks!

Is there any way I can plot several 2D histograms in the same image?
I am doing a phasor plot and I would like to show different lifetime distributions within the universal circle at the same time.

Many thanks for your help in advance.

Sylvain Lannuzel

Thanks a lot for the work done, great feature

Martín Farfán

Gaia Pinardi

great! thanks!
love the avoiding toolbox feature!!!

Weilun Qin

Great work. Thanks.
I found the overall count of data is smaller than the input when I sum(sum(N)). Looks like some are lost, this is not consistent with MATLAB hist3 function. Can this be fixed ?


Great, fast, easy to implement.



Thanks for your code and nice job.

I want to fixe edges as hist3 'Edges' option but I can find how to do this.


Thank you so much for the code!

While I love the figures it generates, I believe there might be an error in computing edges or bin counts for the edges. I used ndhist, with the 3D option, on a 2D matrix. When I counted data that fall within the edges returned by the function, result is different than the N returned by ndhist. Could you please look into this?

Massimo Ciacci

Nice work! The '3d' parameter in particular makes it really worth! It was commented that it would be nice to be able to disable the plotting. Even better than that, I would return handles to the plotted structures, so that one can change their appearance (transparency etc).
Well done!

Andrei Veldman

Very useful! I would recommend to imitate the behavior of hist (and other standard Matlab functions): when nargout > 0, do not plot anything - it's the user's responsibility to do whatever she wants with the outputs.

Hesham Eraqi

Perfect. Exactly what I wanted.


This is great for heatmaps!


hist3 subfunction is brilliant! This is exactly what I need. One question regarding MATLAB 2014b and after. Because histc is not recommended any more and may later being removed, Mathworks advises to use histcounts instead. However, histcounts results in slightly different from histc. Maybe you want to consider update your code to adapt the new version of MATLAB. I know I know, Mathworks keeps doing this and ruins our life. I have bigger headache now for taking care many of my graph related functions since the new MATLAB doesn't use numerical graph id anymore.

Fernando Gonzalez


Great function. How can I use the same colormap for 2 different plots? (the max value would be the max value for plots 1 and 2 instead of each plot having its own range)



Perfect! Nice job,





Jonathan C. Lansey

Nice Josh thanks! I incorporated your code into the program now, pass the parameter '3d' to get a 3d bar graph.

Josh G

Does exactly what I need! Very robust code too.

The only thing I wished it would do is make a nice 3d bar graph from the data.

I wanted to visualize the histogram as a 3d bar graph so I though I would share how I used this function to do that too.

[edgesX2, edgesY2, N] = ndhist(randn(1,1000),randn(1,1000));

% plot histogram in 3d
% bar3 reversed y-axis, set it back to normal
set(gca, 'YDir', 'normal');
% Used to shift x data x = m*x+b
m = (edgesX2(end)-edgesX2(1))/(numel(edgesX2)-1);
b = edgesX2(1)-m;
for i = 1:length(h)
% Rebuild zdata and remove NaN, determined by looking at zdata, this
% removes the uncolored faces that appear if you just set Cdata to
% Zdata.
zdata = get(h(i),'Zdata');
cdata = repmat(reshape(repmat(zdata(2:6:end,2)',6,1),[],1),1,4);
% Shift data in X to get correct axis, set color data
set(h(i), 'XData', get(h(i),'XData')*m+b, 'Cdata',cdata);

% top down view to match ndhist
view([0 0 1]);

Siavash Sakhavi

Excellent Program.

Being independent from toolboxes is the main reason I came for it.

MATLAB Release Compatibility
Created with R2013b
Compatible with any release
Platform Compatibility
Windows macOS Linux

Community Treasure Hunt

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

Start Hunting!