Coloring points via "TemperatureMap" [duplicate]

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];

• A frequently asked question (and duplicate). 2D version: (1300), (5185). 3D duplicates: (20023), (77859), (78289) May 18, 2015 at 16:44
• @Mr.Wizard: Thanks for all those links! May 18, 2015 at 16:49

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
]


(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]

• Thank you! This is just what I needed, the syntax for ColorData["TemperatureMap"][ #[[2]] ]. May 18, 2015 at 21:11
• 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[]. May 18, 2015 at 22:00
• @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! May 18, 2015 at 22:15
• @J.M. I added your version with Apply as an alternative to my answer. I hope you don't mind. May 18, 2015 at 22:24
• 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. May 18, 2015 at 23:34