X-Y scatter plot with coloring dependent on Z value [duplicate]

I have an array of $(x,y,z)$ triples (array dimensions: N x 3), from which I can make a 2D scatterplot of $(x,y)$ values:

t = Table[{Sin[i], Cos[i], i}, {i, 0, 2 \[Pi], N[\[Pi]/20]}];
ListPlot[t[[All, 1 ;; 2]]]

Now, I want to color each point according to its $z$ value. I can find how to do so by creating a series of Disks and putting them all into a Graphics, but then I have to take of absolutely all the formatting. Yet, I can't see how to leverage ListPlot options, such as ColorFunction, to achieve my goal. What would you suggest?

Since your data is essentially 3D, I'll offer another solution which does not require you to roll your own, and is closer to what you intended (i.e., use built-in and change the ColorFunction).

The approach is simple — plot the data in 3D, explicitly color the points according to the $z$-value and view the resulting plot along the $z$-axis (which makes it a 2D plot).

ListPointPlot3D[t, ColorFunction -> (Hue@#3 &), ViewPoint -> {0, 0, ∞}, Axes -> {True, True, False}] The advantage of this over ListPlot is that you can easily associate the $z$-value of each $(x,y)$ pair in the color function since we're actually plotting the triplet $(x,y,z)$, whereas in ListPlot, once you split the list into a list of $(x,y)$ pairs and $z$-values, you'll have to resort to mapping and combining several of them with Show (or other ways), which is clumsy. That said, were I to do this, I would roll my own, since it offers greater control and customizability.

A direct way to "leverage the options" (without otherwise exploiting some alternative workaround to ListPlot) reorganizes the points, using List /@ to make each one a separate part of the plot whose style can be separately specified in parallel with the points list:

ListPlot[List /@ t[[All, 1 ;; 2]],
PlotStyle -> ({PointSize[0.033], Hue[#/(2 \[Pi]), 4/5, 4/5]} & /@ t[[All, 3]]),
AspectRatio -> 1] (The parentheses around the target of PlotStyle -> are essential.)

A (small) disadvantage is apparent: any value of PlotStyle intended to be common to all points, such as their size, has to be part of the specification for each point. The construct here--mapping a list of styles via {...}& /@ over the z-values--is a clean way to write the common style specifications just once each.

• Love that one! And somewhat sad not to have thought of it…
– F'x
Mar 20 '13 at 14:36
• Is this solution acceptable? Points left and right from (0,1) are close to the max and min value of the z-coord. According to the color scale, their z-coord. is almost the same. Apr 4 '13 at 13:32
• That's just an over-reading of the colors, DeeDee: with the hue scale, colors at the two ends are close to each other. Use a different color ramp if you like. Apr 4 '13 at 14:47

If you just care about the options used in your ListPlot, why don't you extract them and use it in your custom made Graphics?

t = Table[{Sin[i], Cos[i], i}, {i, 0, 2 \[Pi], N[\[Pi]/20]}];
opts = AbsoluteOptions[ListPlot[t[[All, 1 ;; 2]]]];

Graphics[{PointSize[.02], {ColorData["Rainbow", Last[#]/(2 Pi)],
Point[Most[#]]} & /@ t}, Sequence @@ opts] Maybe a little faster:

Block[{a, vc, pts},
a = Range[0., 2 Pi, Pi/20.];
pts = Transpose[{Sin[a], Cos[a]}];
vc = ColorData["Rainbow", #] & /@ Rescale[a];
Graphics[{PointSize@.02, Point[pts, VertexColors -> vc]}, Axes -> 1]] • +1 It's about six times faster--potentially a good solution for large lists where the more complex options of ListPlot and its kin are unneeded. Mar 20 '13 at 14:39
• Excellent suggestion, I did not know that VertexColors works with Point and I had performance problems before because I had to break up data into several Points just for colouring. Mar 20 '13 at 14:46

You can wrap the elements of t with Style:

t = Table[{Sin[i], Cos[i], i}, {i, 0, 2 \[Pi], N[\[Pi]/20]}];

ListPlot[Style[#[[;; 2]], PointSize[.02], ColorData["Rainbow"][#[]/Max[t[[All, 3]]]]]&
/@ t, AspectRatio -> 1] Or use BubbleChart:

BubbleChart[t, ColorFunction -> (ColorData["Rainbow"][#3] &),
BubbleSizes -> {0.02, 0.02}, Axes -> True, Frame -> False] This is very hacky but it makes direct use of ColorFunction in ListPlot

t = Table[{Sin[i], Cos[i], i}, {i, 0, 2 \[Pi], N[\[Pi]/20]}];
counter = 1;
ListPlot[t[[All, 1 ;; 2]], Joined -> True,
PlotStyle -> PointSize -> 0.02,
ColorFunction ->
Function[{x, y},
col = ColorData["Rainbow"][t[[counter, 3]]/(2*Pi)];
counter = counter + 1; col]] /. Line -> Point 