MATLAB: How to plot already binned data

2d plotbinsdatadata importgraphhistogramplotplotting

Hi all. I made this code that bins my data (Hs and Tp are 2 1×49 matrices). The data as you can see is already binned in bins that are 0.5 "wide". The bins go from 0 to 15.
datay = Hs;
datax= Tp;
edgesx = 0:0.5:15;
edgesy= 0:0.5:15;
valuesx= edgesx(2:end);
valuesy= edgesy(2:end);
Y= discretize (datay,edgesx,valuesx)
X= discretize(datax,edgesy,valuesy)
XY=[Y;X]
-valuesx and values y are used to assign bin values.
-Discretize is used to distribute the Hs and Tp numerical values into the X and Y bins
I would like to make a code that plots Y vs X as square (since the data has equal edges of 0.5).
The number inside the bin is the bin count (i.e. how many entries in that bin)
My final result should look like something on the lines of this (ignore those lines)
I attempted to reach this result by changing this code : https://uk.mathworks.com/matlabcentral/answers/444262-2d-colour-coded-plot-with-already-binned-data (author @Adam Danz ) but it doesn't work as I think I'm not carefully thinking about the dimension of the matrix I want to plot
datay = Hs;
datax= Tp;
edgesx = 0:0.5:15;
edgesy= 0:0.5:15;
valuesx= edgesx(2:end);
valuesy= edgesy(2:end);
Y= discretize (datay,edgesx,valuesx)
X= discretize(datax,edgesy,valuesy)
XY=[Y;X]
%-------------Modified Code------------
xedges = 0:0.5:30; %Axis should go from 0-30

yedges= 0:0.5:30; %Axis should go from 0-30
% Define bottom, left corner (x,y) of each rectangle
[x, y] = meshgrid(xedges(1:end-1),yedges(1:end-1));
% Determine width and height of each rectangle
[w, h] = meshgrid(diff(xedges), diff(yedges)); %Happy with this as the data is already binned in 0.5 wide rectangle
% Normalize c matrix (0:1)
cNorm = (XY - min(XY(:))) / max(XY(:)); % This is what is not working in my case I think
% Create color matrix
% * you can use any color map: https://www.mathworks.com/help/matlab/ref/colormap.html#buc3wsn-1-map
% * if you change the color map here, change it below as well.
% * I'm setting precision here to 4 decimal places
prec = 1e4;
cmat = parula(prec);
% Assign color (row index) to each value in c
cIdx = round(cNorm * prec);
% loop through each rectangle and draw it
figure
axh = axes;
hold(axh, 'on')
for i = 1:numel(cIdx)
% Don't draw rectangle if color value is 0
if cIdx(i) == 0
continue
end
% Draw rectangle
rh = rectangle(axh, 'Position', [x(i), y(i), w(i), h(i)], ...
'FaceColor', cmat(cIdx(i), :), 'EdgeColor', 'k');
end
% Plot cosmetics
grid(axh, 'on')
colormap(axh, 'parula')
colorbar(axh)
caxis([min(XY(:)), max(XY(:))])
%% Sanity check
% Confirm that edges are correct by drawing lines at edges.
% Save and restore axis limits
yl = ylim;
xl = xlim;
plot([xedges;xedges], repmat(ylim', size(xedges)), 'k-') %x bins, vertical lines
plot(repmat(xlim', size(yedges)), [yedges;yedges], 'k-') %y bins, horizontal lines
xlim(xl)
ylim(yl)

Best Answer

heatmap plots are difficult to customize which is why I recommend using imagesc or histogram2.
This expample below uses histogram2 to produce a plot that looks similar to heatmap plots but doesn't come with the restrictions. See inline comments for details.
% Generate data

rng('default')
Hs = 2.5*randn(1,1000);
Tp = 2.5*randn(1, 1000);
Hs = Hs-min(Hs);
Tp = Tp-min(Tp);
datay = Hs;
datax= Tp;
edgesx = 0:0.5:15;
edgesy= 0:0.5:15;
% Plot histogram2

% * Set DisplayStype to Tile for 2D view

% * Set ShowEmptyBins to Off to hide empty bins

h = histogram2(datax, datay, edgesx, edgesy,...
'DisplayStyle','tile','ShowEmptyBins','off');
colormap('cool') % colormap close to the one in your example

% Plot text labels showing value of 2D bins

% * rounding to closest integer using %.0f

% * Due to small bin size, text labels must be small (6pt font size)

[xTxt, yTxt] = ndgrid(h.XBinEdges(2:end)-h.BinWidth(1)/2, ...
h.YBinEdges(2:end)-h.BinWidth(2)/2);
labels = compose('%.0f', h.Values(h.Values~=0));
xTxt(h.Values==0) = []; % remove 0-bin labels



yTxt(h.Values==0) = []; % remove 0-bin labels
hold on
th = text(xTxt(:), yTxt(:), labels(:),'FontSize',6, ...
'VerticalAlignment', 'Middle', 'HorizontalAlignment','Center');
% Other cosmetics

set(gca, 'xtick', 0:3:15, 'ytick', 0:3:15, ...
'xlim', [0,15], 'ylim', [0,15])
colorbar()
axis equal
% Add text describing labels

text(min(xlim), max(ylim), ...
'*Bin labels are rounded.', 'FontSize', 7, ...
'VerticalAlignment', 'Bottom', 'HorizontalAlignment', 'left')
If you want the image to look even more similar to your example you need to
  • Turn off the bin edge lines
  • Set the face color alpha to something like 50% (0.5) which also requires setting the figure renderer to painters.
% Generate data
rng('default')
Hs = 2.5*randn(1,1000);
Tp = 2.5*randn(1, 1000);
Hs = Hs-min(Hs);
Tp = Tp-min(Tp);
datay = Hs;
datax= Tp;
edgesx = 0:0.5:15;
edgesy= 0:0.5:15;
% Figure renderer must be set to painters if
% your setting the FaceColorAlpha of the
% histogram object, otherwise skip this line.
figure('Renderer','painters')
% Plot histogram2
% * Set DisplayStype to Tile for 2D view
% * Set ShowEmptyBins to Off to hide empty bins
h = histogram2(datax, datay, edgesx, edgesy,...
'DisplayStyle','tile','ShowEmptyBins','off');
colormap('cool') % colormap close to the one in your example
% Set transparency level and turn off bin lines
h.FaceAlpha = .5;
h.LineStyle = 'none';
% Plot text labels showing value of 2D bins
% * rounding to closest integer using %.0f
% * Due to small bin size, text labels must be small (6pt font size)
[xTxt, yTxt] = ndgrid(h.XBinEdges(2:end)-h.BinWidth(1)/2, ...
h.YBinEdges(2:end)-h.BinWidth(2)/2);
labels = compose('%.0f', h.Values(h.Values~=0));
xTxt(h.Values==0) = []; % remove 0-bin labels
yTxt(h.Values==0) = []; % remove 0-bin labels
hold on
th = text(xTxt(:), yTxt(:), labels(:),'FontSize',6, ...
'VerticalAlignment', 'Middle', 'HorizontalAlignment','Center');
% Other cosmetics
set(gca, 'xtick', 0:3:15, 'ytick', 0:3:15, ...
'xlim', [0,15], 'ylim', [0,15])
colorbar()
axis equal
% Add text describing labels
text(min(xlim), max(ylim), ...
'*Bin labels are rounded.', 'FontSize', 7, ...
'VerticalAlignment', 'Bottom', 'HorizontalAlignment', 'left')