# Assigning a Color to each Point on the Plane

I have a dataset consisting of points on the plane and a corresponding color. These colors divide the plane into a few distinct regions. I would like to make a plot or diagram that nicely shows this breakdown into colored regions.

To generate some example data,

incircle[x_, y_] := Piecewise[{{Red, x^2 + y^2 <= 25 }, {Blue, x^2 + y^2 > 25 }}];
data = Table[{i, j, incircle[i, j]}, {i, -10, 10, 1}, {j, -10, 10, 1}];
data = ArrayReshape[data, {441, 3}];

(*{{-10,-10,Blue},{-10,-9,Blue},{-10,-8,Blue},{-10,-7,Blue},...*)


This gives a list where each entry is a pair of x,y coordinates, and then red or blue depending on whether or not the coordinates are within a circle of radius five.

I can then make a list of coordinates and list of colors, and plot them accordingly using listplot:

pdat = {{#[[1]], #[[2]]}} & /@ data;
pcol = #[[3]] & /@ data;
ListPlot[pdat, PlotStyle -> pcol, PlotMarkers -> "\[FilledSquare]", ImageSize -> {250, 250}]


Which gives me a red circular region. Is there anyway to color each region according to the list more nicely and continuously, preserving a definite boundary between each region? My actual data is much more sporadic so the boundary between regions can be much more complex than a circle.

• Aug 13 '20 at 6:55
• It looks like vertexcolors blend colors together between the different regions. Is there a way to preserve a definite boundary between each region? Aug 13 '20 at 7:00
• if each is defined as a point, I don’t think this interpolation should happen. However, if you know certain regions will have certain colors, you might find a way to use a ColorFunction. Aug 13 '20 at 7:10
• Hmmm yes maybe I could do something with colorfunction if I put all my data in a matrix and use arrayplot... Aug 13 '20 at 7:21

# Convex hull mesh

coords = CoordinateBoundsArray[{{-10, 10}, {-10, 10}}];
in = Select[Flatten[coords, 1], Norm@# <= 5 &];
out = Select[Flatten[coords, 1], Norm@# > 5 &];

p1 = Cases[Normal@ConvexHullMesh[out]["Graphics"], _Polygon, Infinity];
p2 = Cases[Normal@ConvexHullMesh[in]["Graphics"], _Polygon, Infinity];

Graphics[{
ColorData[97, 1], First@p1,
ColorData[97, 2], First@p2
}]


If anybody knows of a better way to turn a convex hull mesh into a polygon, please let me know.

# Interpolation

Interpolation with interpolation order 0.

data = Join[{#, 1} & /@ in, {#, 2} & /@ out];
interp = Interpolation[data, InterpolationOrder -> 0];

DensityPlot[
interp[x, y],
{x, -10, 10},
{y, -10, 10},
PlotPoints -> 100
]


Using a higher interpolation order and rounding to get smoothed boundaries:

interp = Interpolation[data, InterpolationOrder -> 1];
DensityPlot[
Round@interp[x, y],
{x, -10, 10},
{y, -10, 10},
PlotPoints -> 100
]


• Concerning ConvexHullMesh: I think MeshPrimitives[mesh, 2] yields a list of the 2-D polygons in the mesh. Aug 13 '20 at 15:26
• Thanks for your response! Would the mesh still work as well if I had multiple disconnected regions? Aug 13 '20 at 16:01
• Interpolation seemed to work well for my data! Aug 13 '20 at 17:53
• That's it, thanks @MichaelSeifert, Aug 13 '20 at 18:02
• @Cheyne ok, good! I haven't looked into how ConvexHullMesh treats disconnected regions. Aug 13 '20 at 18:06

# VoronoiMesh method

points = Drop[data, None, -1];
mesh = VoronoiMesh[points];
polygons = MeshPrimitives[mesh, 2];
coloredpolygons = Map[{incircle @@ RegionCentroid[#], #} &, polygons];
Graphics[coloredpolygons]


VoronoiMesh automatically chooses the coordinates of the boundaries of the mesh, but you can also specify the boundaries via a second argument (VoronoiMesh[points, {{xmin, xmax}, {ymin, ymax}}]) if you want.

This method generalizes nicely to irregularly located points as well.

points = RandomReal[{-10, 10}, {200, 2}];
(* Remaining code as above *)


Note, however, that there is a bug in this code: the centroid of a Voronoi cell is not necessarily its "base point". This may make a difference in some cases, particularly if your base points are not uniformly distributed.

I will have to think if there's an easy way to color the Voronoi cells based on their base point, rather than their centroid. Complicating matters is that MeshPrimitives[VoronoiMesh[points]] appears to shuffle the order of the resulting polygons (i.e., the $$i$$th polygon in the result does not necessarily contain the $$i$$th element of points.)

This looks a bit cleaner, and it does what you want:

pdat1=List/@data[[All,;;2]];
pcol1=List/@data[[All,3]];
ListPlot[pdat1, PlotStyle -> pcol1, PlotMarkers -> "\[FilledSquare]", ImageSize -> {250, 250}]


Same as original output from OP.

This uses VertexColors, but is in Graphics using Point:

Graphics[{PointSize[Medium],Point[data[[All,;;2]],VertexColors->data[[All,3]]]}, ImageSize -> {250, 250},Axes->True]


I’ll add other methods once I am back to a PC.

• This looks the same as OP's image for me. What is the difference? Aug 13 '20 at 7:53
• @C.E. the syntax looks cleaner and may be easier to understand. From what I gather, the OP is looking for a better syntax to color each point, while still keeping them points. Aug 13 '20 at 7:59
• To the down-voter, what is the issue with this answer? Seemingly this is exactly what the OP is asking for. Aug 13 '20 at 8:14
• I'm not the downvoter, but I think that OP may be looking for something like what I posted in my answer. But let's wait and see. Aug 13 '20 at 8:19
• @C.E. Ah this could be true. If that’s the case, I would update my answer. :) Aug 13 '20 at 8:22