8
$\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$
  • $\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$ – AccidentalFourierTransform Apr 23 '18 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 '18 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 '18 at 16:04
10
$\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$
7
$\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$
  • 1
    $\begingroup$ Since the OP raises the specific question of timing, perhaps you ought to time this and compare? $\endgroup$ – Michael E2 Apr 23 '18 at 1:42
  • $\begingroup$ Sure, I'll be edit it. $\endgroup$ – OkkesDulgerci Apr 23 '18 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 '18 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 '18 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 '18 at 13:29

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.