Is there a way to use a colorscheme to a KnotData image?

One way is probably convert it to a parametric form and then use Colorfunction with ParametricPlot3D. The method is described in J.M.'s answer to How to create a new “person curve”?. Although it seems to have some problems with Trefoil.

Is there any simpler way to do this?

In summary, I want to use (say) Colorfunction->Hue with the output of KnotData["Trefoil"].

Using J.M.'s method

FourierCurve[x_, m_, t_, tol_: 0.01] := Module[{rat = Rationalize[#, tol] &, fc},
fc = Take[Chop[Fourier[x, FourierParameters -> {-1, 1}]],
       Min[m, Ceiling[Length[x]/2]]];
       2 rat[Abs[fc]].Cos[Pi (2 Range[0, Length[fc] - 1] t - rat[Arg[fc]/Pi])]]

{f[t_], g[t_], h[t_]} = FourierCurve[#, 20, t] & /@ 
  KnotData["FigureEight", "SpaceCurve"]["ValuesOnGrid"];

ParametricPlot3D[{f[t], g[t], h[t]}, {t, 0, 1}, Axes -> None, 
 Boxed -> False, Method -> {"TubePoints" -> 20}, 
 ColorFunction -> "Rainbow", ViewPoint -> Top] /. 
 Line[pts_, rest___] :> Tube[pts, 1/8, rest]

It works nicely with "FigureEight", "SolomonSeal", "Stevedore". (There is a small hole in the red region which can be fixed by adjusting the PlotRange).

enter image description here

When I try with "Trefoil", it returns

Fourier::fftl: Argument Sin[ValuesOnGrid]+2 Sin[2 ValuesOnGrid] is not a non-empty list or rectangular array of numeric quantities. >>

Using Tube works with the data, but coloring is not very flexible in that case.

Graphics3D[Tube[(KnotData["Trefoil", "SpaceCurve"][#]) 
                 & /@ Range[0, 2.1 Pi, Pi/50], 0.1]]

enter image description here

  • 1
    $\begingroup$ "it seems" - can you include a picture and corresponding code to show why you think it's unsatisfactory? $\endgroup$ Apr 13, 2016 at 12:36
  • $\begingroup$ Thanks @J.M. for the comment. I often forget to put tea bag in my tea :) $\endgroup$
    – Sumit
    Apr 13, 2016 at 13:22
  • 1
    $\begingroup$ The reason it doesn't work on "Trefoil" is that actual trigonometric expressions are used for "SpaceCurve" instead of interpolating functions as with the other knots. $\endgroup$ Apr 13, 2016 at 13:53
  • 1
    $\begingroup$ a way to color Tube is to use VertexColors: e.g., Graphics3D[ Tube[KnotData["Trefoil", "SpaceCurve"] /@ #, 0.1, VertexColors -> Hue /@ #]] &@Range[0, 2 Pi, Pi/50] $\endgroup$
    – kglr
    Apr 13, 2016 at 19:44

2 Answers 2


In this case, the KnotData evaluates directly to a parametric curve,

KnotData["Trefoil", "SpaceCurve"]
(* {Sin[#1] + 2 Sin[2 #1], Cos[#1] - 2 Cos[2 #1], -Sin[3 #1]} & *)

so that no sampling is necessary.

  KnotData["Trefoil", "SpaceCurve"][t], {t, 0, 2 \[Pi]}, 
  PlotRange -> All, Axes -> None, Boxed -> False, ViewPoint -> Top,
  ColorFunction -> "Rainbow"] /. 
 Line[pts_, rest__] :> Tube[pts, 1/8, rest]

enter image description here

Of course, this was true for "FigureEight" as well. But the difference is that "FigureEight" like many of the KnotData objects, is only stored as an interpolating function. Since "Trefoil" is not an interpolating function, it does not have the "ValuesOnGrid" property.

  • 1
    $\begingroup$ …and in fact the reason I used FourierCurve[] on all the other knots was precisely because I wanted simple(?) trigonometric expressions for them like with "Trefoil". $\endgroup$ Apr 13, 2016 at 14:26

We can use Tube as graphics directive in ParametricPlot3D:

 KnotData["Trefoil", "SpaceCurve"][t], {t, 0, 2 π}, 
 PlotRange -> All, Axes -> False, Boxed -> False, 
 ColorFunction -> "Rainbow", 
 PlotStyle -> Tube[.2]]

enter image description here

ParametricPlot3D[{KnotData["Trefoil", "SpaceCurve"][t], 
   KnotData["SolomonSeal", "SpaceCurve"][t], 
   KnotData["FigureEight", "SpaceCurve"][t]},
 {t, 0, 2 π}, 
 PlotRange -> All, Axes -> False, Boxed -> False, 
 ColorFunction -> (ColorData["Rainbow"] @ #4 &), 
 PlotStyle -> {Tube[.25], Tube[.15], Tube[.1]}]

enter image description here


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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