If I have a list and plot it:

sample={{0.0758227, 2.76751, "C"}, {0.230704, 2.773, "B"}, {0.25679, 2.66845,

Now I would like to print each point with a colour based on the third column, say if I have an association:

<|"B" -> 1, "C" -> 2, "S" -> 3|>

then the numbers would be indices of some ColorData, say: ColorData[97] /@ Range[3], then everything that has "B" in the last column is plotted blue, "C" is plotted orange and "S" is plotted green.

Also, I should mention that the sample above is really just a sample, the real list has on the order $10^5$ rows, however, the number of distinct letters in the last column is about 20.

I have found some answers but they deal with plotting each point with different colour.


2 Answers 2


sample = Table[
   {RandomReal[], RandomReal[5], 
    RandomSample[CharacterRange["A", "J"], 1][[1]]}, 10^5];

color = Association@Thread[CharacterRange["A", "J"] -> Range[10]];

SplitBy and SortBy are used rather than GatherBy to control the sequencing of the categories.

data = SplitBy[SortBy[sample, Last], Last];

Module[{categories = (#[[1, -1]] & /@ data)},
  #[[All, 1 ;; 2]] & /@ data,
  Frame -> True,
  Axes -> False,
  PlotStyle -> (ColorData[97][color[#]] & /@ categories),
  PlotLegends -> SwatchLegend[categories]]]

enter image description here

With 10^5 data points it only takes a couple of seconds; however, the data is so dense as to be meaningless unless there is some inherent structure that becomes visible.

sample={{0.0758227, 2.76751, "C"}, {0.230704, 2.773, "B"}, {0.25679, 2.66845, "S"}};
assoc = <|"B" -> 1, "C" -> 2, "S" -> 3|>;

sample2 = sample /. assoc;

ListPlot[Style[{#, #2}, ColorData[97][#3], PointSize[.05]] & @@@ sample2]


ListPlot[List/@sample2[[All,{1,2}]], PlotStyle-> ColorData[97] /@ sample2[[All,3]])]

to get

Mathematica graphics

Both of the above are slow for large input data. Using Graphics gives a faster method:

Graphics[{PointSize[.05], Transpose@{ColorData[97]/@sample2[[All,3]], 
 Point/@sample2[[All, {1,2}]]}}, Axes->True]


Graphics[{PointSize[.05], Point[sample2[[All, {1,2}]], 
  VertexColors->(ColorData[97] /@ sample2[[All,3]])]}, Axes->True]

Mathematica graphics

  • $\begingroup$ Thank but this is way too slow, original ListPlot is about 10 seconds, this has already been running for 3 minutes and nothing. $\endgroup$
    – atapaka
    May 2, 2017 at 3:02
  • $\begingroup$ @leosenko, it is slow. I think using Graphics would be faster. $\endgroup$
    – kglr
    May 2, 2017 at 3:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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