Bivariate colormap (let the colors indicate the average of third vector for each bins)

8 views (last 30 days)
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
Edited: Adam Danz on 27 Feb 2024
> I want to create a bivariate colormap using X and Y. However, instead of making the colors indicate the frequency or bin counts
The first step is to bin the x and y values and to compute the mean of z values within each 2D bin. The binned averages can then be plotted in numerous plotting functions such as histogram2, imagesc, heatmap, or pcolor.
Binning and avaraging
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.
The matrix meanMat contains the averages within the 2D bins. It's preallocated with NaNs which is helpful when plotting the results in pcolor so the missing bins are not visually represented. However, if you're using histogram2, you'll need to preallocate using zeros instead.
[unqBins, ~, binID] = unique([xBin, yBin],'rows');
zGroupMeans = splitapply(@mean,XYZ(:,3),binID);
meanMat = nan(nbins(1),nbins(2)); % or zeros(__)
ind = sub2ind(size(meanMat),unqBins(:,1),unqBins(:,2));
meanMat(ind) = zGroupMeans;
Plotting results
The goal is to plot meanMat which contains the averages of Z within the 2D bins. xbinEdges and ybinEdges define the bin edge. The demos below use the sky colormap (R2023b). If you are using a release prior to R2023b, you can recreate sky using,
n=256;
sky = [linspace(.9,0,n)', linspace(.9447,.447,n)', linspace(.9741,.741,n)'];
Option 1: use pcolor
Add an extra column and row of NaNs to meanMat to display the last row and column.
meanMatPadded = meanMat;
meanMatPadded(:,end+1) = NaN;
meanMatPadded(end+1,:) = NaN;
figure()
pcolor(xbinEdges,ybinEdges,meanMatPadded')
colormap(sky) % R2023b
cb = colorbar();
ylabel(cb, 'mean(z)')
Option 2: use heatmap
Heatmap uses bin centers rather than bin edges. Also note that the direction of the y-axis is flipped in heatmap.
figure()
xbinCenters = xbinEdges(2:end)-diff(xbinEdges)/2;
ybinCenters = ybinEdges(2:end)-diff(ybinEdges)/2;
heatmap(xbinCenters,ybinCenters,meanMat','MissingDataColor','w')
Option 3: use imagesc
Imagesc accepts the array of x and y bin edges but it's only using the first and last edge to define the axis limits. If your bin widths are not uniform, imagesc is not the right solution. NaN values are shown with the first color in the colormap.
figure()
imagesc(xbinEdges,ybinEdges,meanMat')
set(gca,'YDir','normal')
colormap(sky(256))
cb = colorbar();
ylabel(cb, 'mean(z)')
clim([-10 inf])
If you want to add edge lines
xline(xbinEdges)
yline(xbinEdges)
Option 4: use histogram2
For histogram2, the means are entered as BinCounts which only accepts positive values and will not show means of 0s. Therefore, this is not recommended. This also doesn't accept NaN values so meanMat must be recomputed using zeros. Use 'ShowEmptyBins','on' to fill in all undefined bins with the base color.
meanMatz = zeros(nbins(1),nbins(2));
meanMatz(ind) = zGroupMeans;
figure()
histogram2('XBinEdges', xbinEdges, 'YBinEdges', ybinEdges, 'BinCounts', meanMatz, 'DisplayStyle', 'tile')
colormap(sky)
cb = colorbar();
ylabel(cb, 'mean(z)')
This answer was updated on 2/27/2024. It originally only showed the histogram2 demo.
  5 Comments

Sign in to comment.

More Answers (0)

Categories

Find more on Colormaps in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!