2
$\begingroup$

This question already has an answer here:

I have a collection of 3D points, and each is associated with a real number in [0,1]. A typical element looks like {{x,y,z},c} where c is the number to determine the color. (Sample code to generate random data below.) I would like to plot those points, coloring each according to ColorData["TemperatureMap"]. I have been unable to figure out how to get this to work, to arrange for ColorFunction->(???) to use that parameter c rather than x, y, or z to index into "TemperatureMap". This is likely straightforward for those (unlike me) who have mastered ColorFunction and ColorData.

SeedRandom[1]; n = 10; 
pts = Table[RandomReal[{-1, 1}, {3}], {n}]; 
ptsc = Map[{#, RandomReal[]} &, pts];
$\endgroup$

marked as duplicate by Mr.Wizard May 19 '15 at 13:50

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

2
$\begingroup$

As @Mr.Wizard pointed out, multiple interesting solutions to your problem have been proposed on this site. I just wanted to add an observation here.

I realize that you did not say so explicitly, but I would think that many users would try some combination of ListPointPlot3D for this kind of task. However, it has been my impression when using the *3D list plotting functions that they may not always be as polished and agile as their 2D counterpart. I have had a few problems with them, and I am now a bit wary.

I find it often easier to reproduce their behavior by constructing a Graphics3D object explicitly; it is my understanding that it's what those functions do anyway. Similarly in this case, the following is the method I would have come up with, when confronted with your problem. I am using your mock data definitions, just with a few more points.

Graphics3D[
 {PointSize[0.03], ColorData["TemperatureMap"][ #[[2]] ], Point[ #[[1]] ]} & /@ ptsc,
 Axes -> True, Background -> Black
]

Mathematica graphics

(I added a black background because the point colors otherwise had very poor contrast on white; of course it's not required.)


Update:

Exactly the same goal can be achieved more cleanly following Guess who it is's suggestion of using Apply to improve on the somewhat ugly Part expressions I had above:

Graphics3D[
 {PointSize[0.03],
  {ColorData["TemperatureMap"][#2], Point[#1]} & @@@ ptsc
  }, Axes -> True, Background -> Black]
$\endgroup$
  • $\begingroup$ Thank you! This is just what I needed, the syntax for ColorData["TemperatureMap"][ #[[2]] ]. $\endgroup$ – Joseph O'Rourke May 18 '15 at 21:11
  • 2
    $\begingroup$ Also possible: {PointSize[0.03], {ColorData["TemperatureMap"][#2], Point[#1]} & @@@ ptsc}. The PointSize[] will be applied globally anyway, and you can use Apply[] to avoid clumsiness with Part[]. $\endgroup$ – J. M. is away May 18 '15 at 22:00
  • $\begingroup$ @J.M. Good point about the global PointSize. As for the Apply[], I'll be honest: those @@@ still hurt my brain sometimes, but it is undoubtedly more elegant here. I really need to use it more! $\endgroup$ – MarcoB May 18 '15 at 22:15
  • $\begingroup$ @J.M. I added your version with Apply as an alternative to my answer. I hope you don't mind. $\endgroup$ – MarcoB May 18 '15 at 22:24
  • 2
    $\begingroup$ Hello, @Joseph! f @@@ list is shorthand for Apply[f, list, {1}]; it changes the heads of the elements of list at the first level ({1}) to f. So, if you do something like f @@@ {{u, v}, {x, y}}, you get {f[u, v], f[x, y]} as the result, with for instance the List head of {u, v} getting turned into f. $\endgroup$ – J. M. is away May 18 '15 at 23:34

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