5
$\begingroup$

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}]

enter image description here

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.

$\endgroup$
4
  • $\begingroup$ VertexColors? $\endgroup$ Aug 13 '20 at 6:55
  • $\begingroup$ It looks like vertexcolors blend colors together between the different regions. Is there a way to preserve a definite boundary between each region? $\endgroup$
    – Cheyne
    Aug 13 '20 at 7:00
  • $\begingroup$ 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. $\endgroup$ Aug 13 '20 at 7:10
  • $\begingroup$ Hmmm yes maybe I could do something with colorfunction if I put all my data in a matrix and use arrayplot... $\endgroup$
    – Cheyne
    Aug 13 '20 at 7:21
5
$\begingroup$

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
  }]

Output

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
 ]

Output

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
 ]

Output

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

VoronoiMesh method

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

enter image description here

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 *)

enter image description here

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.)

$\endgroup$
0
$\begingroup$

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]

Image output of above code

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

$\endgroup$
7
  • 1
    $\begingroup$ This looks the same as OP's image for me. What is the difference? $\endgroup$
    – C. E.
    Aug 13 '20 at 7:53
  • $\begingroup$ @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. $\endgroup$ Aug 13 '20 at 7:59
  • $\begingroup$ To the down-voter, what is the issue with this answer? Seemingly this is exactly what the OP is asking for. $\endgroup$ Aug 13 '20 at 8:14
  • 2
    $\begingroup$ 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. $\endgroup$
    – C. E.
    Aug 13 '20 at 8:19
  • 1
    $\begingroup$ @C.E. Ah this could be true. If that’s the case, I would update my answer. :) $\endgroup$ Aug 13 '20 at 8:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.