MATLAB: How to show bin counts’ percentage values in Histogram2 tile plot

checkerboxdisplaystylehistogram2MATLABplotresidencytile

Hi Dear Community
I have x and y values*, I want to plot it like a 3D Histogram but on the top view. (It should look like a heatmap with a colorbar).
I made the plot, but I want to show the values percentages or counts on the each rectangle. Here is the code below:
hFig = figure;
hAxes = axes(hFig);
xVals = randn(1,10000);
yVals = randn(1,10000)*5;
xEdges = min(xVals):1:max(xVals);
yEdges = min(yVals):5:max(yVals);
hHist = histogram2(hAxes,xVals,yVals,xEdges,yEdges,'DisplayStyle','tile');
colorbar;
This code only plots the tiled histogram. I looked the hHist object and saw that it has the BinCounts property which actually gives the number of points in each rectangle.
So I calculated percentages as follows:
percentagesMatrix = (hHist.BinCounts / sum(hHist.BinCounts,'all'))*100;
I don't know how to update the rectangles with this percentage values. I want all that matrix is written inside the boxes. And update the colorbar accordingly.
Any help will be appreciated.
Thank you so much! 🙂
*Note: x and y values normally comes from a tall table as a tall array.
Here is the sample plot below. I want to see numbers inside these squares:
Capture.JPG

Best Answer

I have solved it writing a function manually add text to each rectangle.
Here is the function:
function hHist = normalized_histogram2(hAxes,xVals,yVals,xEdges,yEdges)
% Creates a 2D Histogram plot of data counts percentage in each bins.
% Add percentage values as text inside each bin.
% Font size and font weight can be changed manually inside the code or
% added to function inputs.
% NOTE: If text does not fit the rectangles, change font size or maximize
% figure plot.
%% inputs:
% hAxes - axis handle object for the plot
% xVals - a double vector of x values
% yVals - a double vector of y values
% NOTE: xVals and yVals must be the same length
% xEdges - a double vector of x bins
% yEdges - a double vector of y bins
%% outputs:
% hHist - histogram object handle
hist_Counts = histcounts2(xVals,yVals,xEdges,yEdges);
hist_Counts_normalized = (hist_Counts / sum(hist_Counts,'all'))*100;
hHist = histogram2(hAxes,'XBinEdges',xEdges,'YBinEdges',yEdges,'DisplayStyle','tile','BinCounts',hist_Counts_normalized);
colorbar;
xBinCenters = hHist.XBinEdges - [0,diff(hHist.XBinEdges)/2];
yBinCenters = hHist.YBinEdges - [0,diff(hHist.YBinEdges)/2];
for i = 2:numel(xBinCenters)
for j = 2:numel(yBinCenters)
x_loc = xBinCenters(i);
y_loc = yBinCenters(j);
if ~(round(hHist.Values(i-1,j-1),2) == 0)
text(hAxes,x_loc,y_loc,[num2str(round(hHist.Values(i-1,j-1),2)),'%'],'Color',[0 0 0],'FontSize',10,'FontWeight','bold');
else
continue
end
end
end
Here is the demo:
%% Data Creation:
xVals = randn(1,10000);
yVals = randn(1,1000)*5;
xEdges = min(xVals):1:max(xVals);
yEdges = min(yVals):5:max(yVals);
%% Demo:
hFig = figure;
hAxes = axes(hFig);
normalized_histogram2(hAxes,xVals,yVals,xEdges,yEdges);
% make plot look beautiful:
xlabel('X Data');
ylabel('Y Data');
title('Normalized Histogram 2');
hFig.WindowState = 'maximized';
It will look like below:
Capture.JPG