3
$\begingroup$

I have about 200000 points, using ListPlot with ColorFunction takes too long. Here is a minimal example with 5000 points which takes 7 sec.

dataA = Get[
   "https://www.dropbox.com/s/kf9ojjoe9na0rft/data.dat?dl=1"];    

this is a custom color

colF[arg_] := Blend[{Gray, Blue}, Rescale[arg, {0, 1}]]    

and visualizing the data as

ListPlot[dataA[[All, 1 ;; 2]], ColorFunctionScaling -> False, 
  ColorFunction -> 
   Function[{x, y}, 
    colF[dataA[[Position[dataA[[All, 1]], x][[1, 1]], 
       3]]]]] // AbsoluteTiming     

enter image description here

However, without coloring, it takes 0.1 sec

ListPlot[dataA[[All, 1 ;; 2]]] // AbsoluteTiming    

enter image description here

$\endgroup$
4
  • $\begingroup$ You are calling Position for every point in the list. This causes $O(n^2)$ time complexity for the plot, where $n$ is the length of the list. There are multiple options which you could employ, but one I'd suggest would be ditching ColorFunction and using Style on each item, which should, if I understand your code correctly, avoid the need for Position. $\endgroup$
    – kirma
    Dec 20, 2022 at 8:20
  • $\begingroup$ ListPlot[Style[{#1, #2}, colF[#3]] & @@@ dataA] should accomplish the same task as your code with ColorFunction, but interestingly there seems to be a scalability issue in styled ListPlot. I'll probably write a bug report on this... $\endgroup$
    – kirma
    Dec 20, 2022 at 8:40
  • 1
    $\begingroup$ @kirma, I tried that but it takes a long time too. $\endgroup$
    – MMA13
    Dec 20, 2022 at 8:42
  • 1
    $\begingroup$ Oh wow, interestingly enough ColorFunction is actually a lot more efficient that Style. So, my advice is actually not that great (apart from getting rid of repeated Position calls). $\endgroup$
    – kirma
    Dec 20, 2022 at 8:55

2 Answers 2

10
$\begingroup$

Removing the repeated calls of Position on ColorFunction and replacing them with use of a precomputed dispatch table improves performance quite a bit:

With[{color = Dispatch[#1 -> colF[#3] & @@@ dataA]},
  ListPlot[dataA[[All, 1 ;; 2]],
   ColorFunctionScaling -> False, 
   ColorFunction -> Function[{x, y}, x /. color]]] //
 AbsoluteTiming

enter image description here

$\endgroup$
1
  • $\begingroup$ Both solutions are amazing, but I will accept the one with ListPlot $\endgroup$
    – MMA13
    Dec 29, 2022 at 14:06
10
$\begingroup$

Graphicsis factor 20 faster than ListPlot in this example:

data = RandomReal[{0, 1}, {5000, 3}];
Graphics[Map[{Blend[{Gray, Blue}, Rescale[#[[3]], {0, 1}]],Point@Most[#]} &, data] ] // AbsoluteTiming 
(* {.027,...}*)
$\endgroup$

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.