# Binned bivariate colormap(let the colors indicate the average of third properties for the bins

4 views (last 30 days)
Luphi Gao on 18 Apr 2021
Commented: Luphi Gao on 19 Apr 2021
Hello all,
I have 3 data vectors: X Y and Z, all with the same length. Each (X(i), Y(i)) has a corresponding Z(i) (The reference data is attached). I want to create a bivariate colormap using X and Y. However, instead of making the colors indicate the frequency or bin counts (like the figure shown below), how could I make the colors represent the average value of Z for the events in a given bin. Thank you so much Adam Danz on 19 Apr 2021
Edited: Adam Danz on 19 Apr 2021
The idea is to bin the x and y values and to compute the mean of z values within each bin. Those data can be used in histogram2, imagesc, heatmap, etc to display the binned averages.
nbins = [20,20]; % x,y number of bins
xbinEdges = linspace(min(XYZ(:,1)),max(XYZ(:,1)*1.0001),nbins(1)+1);
ybinEdges = linspace(min(XYZ(:,2)),max(XYZ(:,2)*1.0001),nbins(2)+1);
% The *1.0001 is to avoid excluding the max values from the final bins.
Identify the bin number of the x and y values
xBin = discretize(XYZ(:,1),xbinEdges);
yBin = discretize(XYZ(:,2),ybinEdges);
Average the Z values within each bin within a nxm matrix for n x-bins and m y-bins.
[unqBins, ~, binID] = unique([xBin, yBin],'rows');
zGroupMeans = splitapply(@mean,XYZ(:,3),binID);
meanMat = zeros(nbins(1),nbins(2));
ind = sub2ind(size(meanMat),unqBins(:,1),unqBins(:,2));
meanMat(ind) = zGroupMeans;
Show the binned means using histogram2
Use 'ShowEmptyBins','on' to fill in all bins with the base color.
histogram2('XBinEdges', xbinEdges, 'YBinEdges', ybinEdges, 'BinCounts', meanMat, 'DisplayStyle', 'tile')
axis square % or equal
cb = colorbar();
ylabel(cb, 'mean(z)')
Define bivariate colormap
This uses Matlab's heatmap colormap.
n=256;
cmap = [linspace(.9,0,n)', linspace(.9447,.447,n)', linspace(.9741,.741,n)'];
set(gca,'Colormap',cmap)
(Optional) Verify correct binning by placing a red x over the bin with the greatest mean.
% verify binning
[~, maxidx] = max(zGroupMeans);
xTest = mean(xbinEdges(unqBins(maxidx,1)+[0,1]));
yTest = mean(ybinEdges(unqBins(maxidx,2)+[0,1]));
hold on
plot(xTest, yTest,'rx','MarkerSize',10,'LineWidth',2) If you want the image to look more similar to the example you shared, you can remove the grid (grid off) and remove the bin edge lines ('edgecolor','none').
Luphi Gao on 19 Apr 2021