필터 지우기
필터 지우기

Scattered heat map based on frequency

조회 수: 43 (최근 30일)
Lucas
Lucas 2023년 8월 7일
편집: Voss 2023년 8월 8일
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