# ContourPlot -- coloring the plot lines

I have 2D implicit functions which I would like to plot in color, with given color functions.

E.g.:

ContourPlot[y^2 - x^3 + x^4 == 0, {x, 0, 1}, {y, -1/2, 1/2}]


but with the coloring we get from, e.g. (or ParametricPlot):

Plot[Sinc[x], {x, 0, 10}, PlotStyle -> Thick, ColorFunction -> Function[{x, y}, ColorData["NeonColors"][y]]]


(Note that this is possible for ContourPlot3D.)

The implicit functions cannot easily be transformed to explicit or parametric forms.

The only thing I thought of was to numerically map out the 2D space, run over the pixels, see if they adhere to the given constraint, and if so, ListPlot the points with the color function.

EDIT: I can actually get the relevant x-y coordinates out of the initial ContourPlot.

Other ideas are welcome. Thank you.

• Thank you, but I would like the color to change by pixel, and not one color per contour. Jun 19, 2022 at 16:07

ListPlot[MeshPrimitives[
ContourPlot[y^2 - x^3 + x^4 == 0, {x, 0, 1}, {y, -1/2, 1/2},
PlotPoints -> 50, MaxRecursion -> 4] // DiscretizeGraphics,
1][[;; , 1]], Joined -> True,
ColorFunction -> Function[{x, y}, ColorData["NeonColors"][y]]]


• Excellent, thanx, I'm onto it! Jun 19, 2022 at 16:06

Test plot:

cplot = ContourPlot[y^2 - x^3 + x^4 == 0, {x, 0, 1}, {y, -1/2, 1/2}];


With color function scaling.

p1 = cplot /. GraphicsComplex[p_, g_, opts___] :> With[{
pp = Transpose[Rescale /@ Transpose@p], (* ColorFunctionScaling->True *)
cf = ColorData["Rainbow"][#2] &},       (* color function *)
GraphicsComplex[p,
g /. Line[i_] :> Line[i, VertexColors -> cf @@@ pp[[i]]], opts]
]


Without color function scaling. The pp = p is unnecessary; if it is removed, change the remaining instances of p and pp to the same symbol.

p2 = cplot /. GraphicsComplex[p_, g_, opts___] :> With[{
pp = p, (* ColorFunctionScaling -> False *)
cf = ColorData["Rainbow"][0.3 + #2] &},
GraphicsComplex[p,
g /. Line[i_] :> Line[i, VertexColors -> cf @@@ pp[[i]]], opts]
]


With coloring according to scaled arc length. It's advisable to check how many lines were constructed. Each line is colored according to its own scaled arc length measured from whatever point happens to be its first.

Count[cplot, _Line, Infinity]
(*  1  *)

p3 = cplot /. GraphicsComplex[p_, g_, opts___] :> With[{
pp = p, (* ColorFunctionScaling -> False *)
cf = Hue},
GraphicsComplex[
p,
g /. Line[i_] :> Line[
i,
VertexColors ->
cf /@
Rescale@
Accumulate@Prepend[Norm /@ Partition[pp[[i]], 2, 1], 0.]],
opts]
]


Colored according to function of x and y.

scalingFN = Exp[Sin[3 #1 + 2 #2]] &;
p4 = cplot /. GraphicsComplex[p_, g_, opts___] :> With[{
pp = Rescale[scalingFN @@@ p], (* Scaled by f[x,y] *)
cf = ColorData["TemperatureMap"]},
GraphicsComplex[p,
g /. Line[i_] :> Line[i, VertexColors -> cf /@ pp[[i]]], opts]
]


Results, in respective order:

Remarks: Note the differences cf @@@ ... and cf /@ ... depending on whether cf is applied to points or to scalars constructed from the points. The code above for color function scaling was given in general. The particular example could be done with  pp = Rescale[p[[All, 2]]], cf = ColorData["Rainbow"], and cf /@ pp, This code (in its variations) works on GraphicsComplex only.

• This is great as well, although I think I have all I need from @cvgmt's reply. Jun 19, 2022 at 17:53
• @AharonNaiman NP. There's an external simplicity to the other method even though something more complicated is happening internally. (Compare the ByteCount/timing of the two methods: 200K/0.06 sec vs 40K/0.0006 sec for p1, not including ContourPlot. If we change p1 to VertexColors -> DeveloperToPackedArray[List @@@ cf @@@ pp[[i]]]`, the mem drops to 18K and the time stays roughly the same.) Jun 19, 2022 at 21:20
• Wow, that is significant! I did notice the amount of time my problems took to run. I'll keep this in mind. Thank you again. Jun 20, 2022 at 11:01