MATLAB Answers

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

35 views (last 30 days)
Luphi Gao
Luphi Gao on 18 Apr 2021 at 2:37
Commented: Luphi Gao on 19 Apr 2021 at 21:03
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

Accepted Answer

Adam Danz
Adam Danz on 19 Apr 2021 at 16:19
Edited: Adam Danz on 19 Apr 2021 at 16:25
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.
Load data, create bin edges
load('XYZ.mat')
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').

More Answers (0)

Community Treasure Hunt

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

Start Hunting!