7
$\begingroup$

I have a list of (x,y) points I would like to plot with each point a specific color. ListPlot is substantially slower when I assign each point a color than when I use the default single color for each point.

Any idea on how to speed up?

Below is test code where I have assigned one of four colors randomly. Note the timing.

Thanks.

n = 10^4;
locs = Table[{RandomReal[] , RandomReal[]} , n];
c = RandomChoice [ {Red, Green, Blue, Black} , n];
t0 = TimeUsed[];
p1 = ListPlot[locs, ImageSize -> 800];
t1 = TimeUsed[];
p2 = ListPlot[List /@ locs, ImageSize -> 800, PlotStyle -> c];
t2 = TimeUsed[];
Print [ "All same color = ", t1 - t0 , " cpu seconds." ];
Print["Each point its own color = " , t2 - t1 , " cpu seconds." ];

All same color = 0.115 cpu seconds. Each point its own color = 7.015 cpu seconds

$\endgroup$
3
  • $\begingroup$ Note: you can use Timing (or AbsoluteTiming) to measure how much time it takes to execute some command. For example, p1 = ListPlot[locs, ImageSize -> 800]; // AbsoluteTiming yields 0.1 seconds and p2 = ListPlot[List /@ locs, ImageSize -> 800, PlotStyle -> c]; // AbsoluteTiming yields 9.3 seconds. No need to use that t0 = TimeUsed[]; trickery. $\endgroup$ Apr 23, 2018 at 1:15
  • $\begingroup$ What about Graphics[Point[locs, VertexColors -> c], Options@ListPlot]? What you lose is automatic PointSize[] determination.... $\endgroup$
    – Michael E2
    Apr 23, 2018 at 1:28
  • $\begingroup$ FWIW the trick of coloring the data mathematica.stackexchange.com/a/80403/2079 turns out to be extremely slow.. $\endgroup$
    – george2079
    Apr 23, 2018 at 16:04

2 Answers 2

9
$\begingroup$

VertexColors is an efficient way. You can use it with p1 as follows (it adds very little time):

p4 = p1 /. Point[p_] :> Point[p, VertexColors -> c]; // AbsoluteTiming
p4

(*  {0.000087, Null}  *)

Mathematica graphics

You can also apply it directly in Graphics, although you lose the automatic PointSize[] control:

Graphics[Point[locs, VertexColors -> c], Options@ListPlot]

Mathematica graphics

$\endgroup$
6
$\begingroup$

How about this. Not fancy but fast. Make sure n is divisible by 4 which is # of colors.

n = 10^4;
locs = RandomReal[{0, 1}, {n, 2}];
locs2 = Partition[locs, n/4];
ListPlot[locs]; // AbsoluteTiming // First

0.107778

Show[ListPlot[locs2[[1]], PlotStyle -> {Red}], 
    ListPlot[locs2[[2]], PlotStyle -> {Green}], 
    ListPlot[locs2[[3]], PlotStyle -> {Blue}], 
    ListPlot[locs2[[4]], PlotStyle -> {Black}]]; // 
  AbsoluteTiming // First

0.158271

enter image description here

n = 10^4;
locs = Table[{RandomReal[], RandomReal[]}, n];
c = RandomChoice[{Red, Green, Blue, Black}, n];
p2 = ListPlot[List /@ locs, ImageSize -> 800, PlotStyle -> c]; // 
  AbsoluteTiming // First

7.67799

$\endgroup$
5
  • 1
    $\begingroup$ Since the OP raises the specific question of timing, perhaps you ought to time this and compare? $\endgroup$
    – Michael E2
    Apr 23, 2018 at 1:42
  • $\begingroup$ Sure, I'll be edit it. $\endgroup$ Apr 23, 2018 at 1:43
  • $\begingroup$ Thanks for the reminder about AbsoluteTiming. As usual, there;'s always a more elegant way to learn. The Partitioning works but I should have been clearer that in the actual application, the colors have meaning as opposed to the random assignment I made for the example. In other words, each point is one of four colors for a specific reason so I need to carry that info along. $\endgroup$
    – jmm
    Apr 23, 2018 at 2:31
  • 2
    $\begingroup$ note this approach can be automated as ListPlot[#[[All, All, 1]],PlotStyle -> #[[All, 1, 2]]] &@GatherBy[Transpose[{locs, c}], #[[2]] &] (with c as in original post ) $\endgroup$
    – george2079
    Apr 23, 2018 at 17:07
  • $\begingroup$ And with @george2079 's code, it's not dependent on a prescribed structure and correspondence of the data and colors, but seems more fitting with the OP's original formulation of the problem. $\endgroup$
    – Michael E2
    Apr 24, 2018 at 13:29

Your Answer

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

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