Border of a scatter plot in Matlab: constructing it and colouring it

Viewed 163

I would like your help to plot the border of a scatter in Matlab and fill it with a specified colour.

Let me firstly show you how the scatter looks like.

scatter(x,y)

enter image description here

Now, let me show you what I have tried to design the border.

k = boundary(x,y);
plot(x(k),y(k));

which produces this enter image description here

This is not what I want. Firstly, the scatter is nicely convex and I don't understand why boundary produces that weird shape. Secondly, I want to colour with blue inside the border.

Could you kindly advise on how to proceed? Also, when building the border I would prefer not to rely on the convexity of the scatter, because in some of my real examples the scatter is not convex.

1 Answers

Boundary

There is no easy way to get the boundary of a non-convex shape without any information on what is expected. When should the boundary follow the convex hull and when should deviate from it? Matlab function boundary is generic, made to work with arbitrary input coordinates. It has a 'shrink factor' parameter s that can be tuned between 0 (convex hull) and 1 (highly non-convex), depending on the expected result.

% Make some x,y data with a missing corner
[x,y]=meshgrid(1:20);
sel=~(x>15 & y<=5);
x=x(sel);y=y(sel);

% Compute boundary with several values for s
k=boundary([x,y]);            %Default shrink factor : 0.5
k_convhull=boundary([x,y],0);
k_closest=boundary([x,y],1);

% Plot the boundary:
plot(x,y,'ok') %black circles
hold on
plot(x(k),y(k),'-r') %red line
plot(x(k_convhull),y(k_convhull),'-g') %green line
plot(x(k_closest),y(k_closest),'-b') %blue line

The re-entrant corner is still somewhat cut, even with the 'shrink factor' set to 1. If this does not suit you, you will need to make your own function to compute the coordinates of the border.

Plot a surface

You need to use a patch object there.

p=patch(x(k3),y(k3),[1 .8 .8]);
uistack(p,'bottom')

[1 .8 .8] is the RGB color of the patch surface (light pink) uistack is there to move the patch below the other graphic objects, because it is not transparent. It will still cover the axes grid, if any. Another option is :

p=patch(x(k3),y(k3),[1 0 0],'FaceAlpha',.2);

Here, the patch will be plain red and drawn on top of other objects, but has 80% transparency set through the alpha channel (0 is fully transparent, 1 is solid color).

Beware, the patch object class has so many options that is somewhat complex to handle beyond basic use cases like this one.

Related