Scattered heat map based on frequency

38 次查看(过去 30 天)
I have data that says tell an objects position. There is one variable for x and one for y, the values range from -5 to 5. I want to create a scatter plot of this data with the heat map based on frequency. Lets say the position is at (0,0) for 100 data points, I need that to look hotter in color than the one data point at (0,5). Can you please help?
Xpos = column array of double values
Ypos = column array of double values
I've tried implement this code:
color = colormap(jet);
scatter(xpos, ypos, [], color)
but I get the error:
Error using scatter (line 103)
Color must be one RGB triplet, an m-by-3 matrix of RGB triplets with one color per scatter point, or an m-by-1 vector with one value per scatter point.

采纳的回答

Voss
Voss 2023-8-8
编辑:Voss 2023-8-8
Create some random data of the specified size and range:
Xpos = 10*rand(100,1)-5; % column array of double values
Ypos = 10*rand(100,1)-5; % column array of double values
Introduce some data near (0,0), for illustration purposes:
Xpos(20:26) = rand(7,1)-0.5;
Ypos(20:26) = rand(7,1)-0.5;
I'm going to use histcounts2 to do 2d histogram binning on this data, and then map the counts to colors for the scatter plot.
First, define the bin edges for histcounts2:
x_edges = -5.5:5.5;
y_edges = -5.5:5.5;
Now, perform 2d histogram counts. Output c is a matrix of counts. in general, it contains some elements that are 0, because there was no data within those bins. binX and binY are the indices telling us which X- and Y-bin each data point ended up in.
[c,~,~,binX,binY] = histcounts2(Xpos,Ypos,x_edges,y_edges);
We need to transform those binX and binY indices into linear indices in the count matrix c. I use sub2ind for that.
idx = sub2ind(size(c),binX,binY);
And then keep only those c values. (Note that, of course, multiple data points can end up in the same bin, which means that idx can have repeated values.)
c = c(idx);
So now c is a column vector the same size as binX and binY (and Xpos and Ypos), and c tells us the count # of the bin for each (Xpos,Ypos) point.
Now, create the colormap to use. min_c is the minimum count in any bin (remember c is now the bin counts for the data, so c has no zero elements anymore). max_c is the maximum count in any bin. cmap is a 'jet' colormap with ncolors colors.
min_c = min(c);
max_c = max(c);
ncolors = max_c-min_c+1;
cmap = jet(ncolors);
Now use ind2rgb to map the counts in c into RGB colors, according to the colormap cmap. Note that ind2rgb for integer-type data maps 0 to the first color in the colormap, but in this case we want the minimum value of c (i.e., min_c, the lowest number of counts in a bin) to map to the first color, so we subtract off min_c from c before converting to integer and sending to ind2rgb. Then permute the result so it's ncolors-by-3 instead of ncolors-by-1-by-3.
RGB = permute(ind2rgb(uint8(c-min_c),cmap),[1 3 2]);
Finally, scatter plot the data with those colors,
scatter(Xpos,Ypos,[],RGB,'.')
set up ticks and grid for illustration of the bins used,
xticks(x_edges)
yticks(y_edges)
grid on
and set up the colormap and colorbar.
colormap(cmap);
cb = colorbar();
cb.Ticks = (1:2:2*ncolors-1)/(2*ncolors);
cb.TickLabels = 1:ncolors;
cb.Label.String = 'Bin Count';
  2 个评论
Voss
Voss 2023-8-8
Notice that the above method uses colors and counts that may not actually exist in the data. For example, for the random data above there are no bins with 6 points or 5 points, yet the colors for 5 and 6 are defined in the colormap and shown in the colorbar.
An alternative that may be useful is to use only enough colors as necessary, i.e., only as many colors as you have distinct bin counts. Something like this:
Xpos = 10*rand(100,1)-5; % column array of double values
Ypos = 10*rand(100,1)-5; % column array of double values
Xpos(20:26) = rand(7,1)-0.5;
Ypos(20:26) = rand(7,1)-0.5;
x_edges = -5.5:5.5;
y_edges = -5.5:5.5;
[c,~,~,binX,binY] = histcounts2(Xpos,Ypos,x_edges,y_edges);
idx = sub2ind(size(c),binX,binY);
c = c(idx);
[uc,~,jj] = unique(c);
ncolors = numel(uc);
cmap = jet(ncolors);
RGB = permute(ind2rgb(uint8(jj-1),cmap),[1 3 2]);
scatter(Xpos,Ypos,[],RGB,'.')
xticks(x_edges)
yticks(y_edges)
grid on
colormap(cmap);
cb = colorbar();
cb.Ticks = (1:2:2*ncolors-1)/(2*ncolors);
cb.TickLabels = uc;
cb.Label.String = 'Bin Count';
Voss
Voss 2023-8-8
编辑:Voss 2023-8-8
Another (different, and easier) approach is to use histogram2 to make the plot. It's not a scatter plot, but maybe it's sufficient for what you need to do.
Xpos = 10*rand(100,1)-5; % column array of double values
Ypos = 10*rand(100,1)-5; % column array of double values
Xpos(20:26) = rand(7,1)-0.5;
Ypos(20:26) = rand(7,1)-0.5;
x_edges = -5.5:5.5;
y_edges = -5.5:5.5;
h = histogram2(Xpos,Ypos,x_edges,y_edges,'DisplayStyle','tile');
colormap(jet)
cb = colorbar();
cb.Label.String = 'Bin Count';

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Colormaps 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by