# X-Y scatter plot with coloring dependent on Z value

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?

-
Similar question: mathematica.stackexchange.com/q/21130/685 –  VLC Mar 20 '13 at 15:39
Possible duplicates: (1300) (5185) –  Mr.Wizard Mar 20 '13 at 17:30

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. –  DeeDee 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. –  whuber 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]


-
+1 Clever and flexible. –  whuber Mar 20 '13 at 14:29

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. –  whuber 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. –  Szabolcs 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"][#[[3]]/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


-