7

How does one draw a path that is changing color as a function of the path length and is decorated with arrows at the same time? Basically, I want to combine these to figure into one:

enter image description here

The code for the example is:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\usepgfplotslibrary{colormaps}
\usetikzlibrary{decorations.markings}
\tikzset{
  set arrow inside/.code={\pgfqkeys{/tikz/arrow inside}{#1}},
  set arrow inside={end/.initial=>, opt/.initial=},
  /pgf/decoration/Mark/.style={
    mark/.expanded=at position #1 with
    {
      \noexpand\arrow[\pgfkeysvalueof{/tikz/arrow inside/opt {\pgfkeysvalueof{/tikz/arrow inside/end}}
    }
  },
  arrow inside/.style 2 args={
    set arrow inside={#1},
    postaction={
      decorate,decoration={
        markings,Mark/.list={#2}
      }
   }
  },
}


\begin{document}
\begin{tikzpicture}

    \begin{scope}
        \draw[->, ultra thick, >=stealth, line cap=round] (0.0, -2.5) -- (0.0, 2.5);
        \draw[->, ultra thick, >=stealth, line cap=round] (-2.5, 0.0) -- (2.5, 0,0);
        \begin{axis}[x=1cm, y=1cm, ticks=none, axis lines=none, colormap/hot, anchor=origin]
           \addplot[mesh, ultra thick, point meta=\thisrow{c}, shader=interp] table[x=x, y=y] {spiral.dat};
        \end{axis}
    \end{scope}


    \begin{scope}[xshift=6cm]
        \draw[->, ultra thick, >=stealth, line cap=round] (0.0, -2.5) -- (0.0, 2.5);
        \draw[->, ultra thick, >=stealth, line cap=round] (-2.5, 0.0) -- (2.5, 0,0);
        \draw[ultra thick] plot file {spiral_xy.dat} [arrow inside={end=stealth,opt={black, scale=1.05}}{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9}];
    \end{scope}

\end{tikzpicture} 
\end{document}

For the arrow tips I used the solution from Drawing arrows along a function in pgfplots. However, this does not seem to be compatible with the pgfplots mesh command I am using to draw a colored line. I was thinking to combine a mesh and a quiver plot but then the arrow tips would not change color along with the curve. As an alternative one could define a custom fading with \fadingfrompicture but this would be a lot of work for complicated curves. Is there a more simple solution?

  • I do not know the answer, but I suggest providing your MWE and looking into charting multiple sections of a function limited by the argument ranges, each with a different color/gradient. – ajeh Dec 2 '14 at 14:33
  • You may want to have a look to Path following color gradient in TikZ. – Claudio Fiandrino Dec 2 '14 at 14:36
5

My approach relies on the idea to use draw=none for the decorated path.

I chose to use two \addplot commands in an axis (as that simplifies my parametric plot), but that is essentially equivalent to a separate tikz path: decorations can be applied even if the main path has draw=none:

enter image description here

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\usepgfplotslibrary{colormaps}
\usetikzlibrary{decorations.markings}
\tikzset{
  set arrow inside/.code={\pgfqkeys{/tikz/arrow inside}{#1}},
  set arrow inside={end/.initial=>, opt/.initial=},
  /pgf/decoration/Mark/.style={
    mark/.expanded=at position #1 with
    {
      \noexpand\arrow[\pgfkeysvalueof{/tikz/arrow inside/opt}]{\pgfkeysvalueof{/tikz/arrow inside/end}}
    }
  },
  arrow inside/.style 2 args={
    set arrow inside={#1},
    postaction={
      decorate,decoration={
        markings,Mark/.list={#2}
      }
    }
  },
}


\begin{document}
\begin{tikzpicture}

    \draw[->, ultra thick, >=stealth, line cap=round] (0.0, -1.5) -- (0.0, 1.5);
    \draw[->, ultra thick, >=stealth, line cap=round] (-1.5, 0.0) -- (1.5, 0,0);
    \begin{axis}[x=1cm, y=1cm, ticks=none, axis lines=none, colormap/hot, anchor=origin,
    trig format plots=rad, domain=0.1:1, variable=t, point meta=t,
    ]
        \def\helixX{{t*sin(4.5*t*pi)}}
        \def\helixY{{-t*cos(4.5*t*pi)}}
        \addplot[mesh, line cap=round,samples=51,ultra thick,shader=interp] 
            (\helixX,\helixY);

        \addplot[samples=35,draw=none] 
            (\helixX,\helixY)
            [arrow inside={end=stealth,opt={black, scale=1.05}}{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9}]
        ;
    \end{axis}
\end{tikzpicture} 
\end{document}

EDIT

Here is a solution in which the colors vary as well. It needs to define the special color "manually" based on the PGF decoration.

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\usepgfplotslibrary{colormaps}
\usetikzlibrary{decorations.markings}

\def\definemappedcolor#1{%
    %\message{Got #1^^J}%
    \pgfmathparse{#1*1000}% ... transform to range [0,1000]
    \pgfplotscolormapdefinemappedcolor{\pgfmathresult}%
}%

\tikzset{
  set arrow inside/.code={\pgfqkeys{/tikz/arrow inside}{#1}},
  set arrow inside={end/.initial=>, opt/.initial=},
  /pgf/decoration/Mark/.style={
    mark/.expanded=at position #1 with
    {
      \noexpand\definemappedcolor{#1}%
      \noexpand\arrow[\pgfkeysvalueof{/tikz/arrow inside/opt}]{\pgfkeysvalueof{/tikz/arrow inside/end}}
    }
  },
  arrow inside/.style 2 args={
    set arrow inside={#1},
    postaction={
      decorate,decoration={
        markings,Mark/.list={#2}
      }
    }
  },
}


\begin{document}
\begin{tikzpicture}

    \draw[->, ultra thick, >=stealth, line cap=round] (0.0, -1.5) -- (0.0, 1.5);
    \draw[->, ultra thick, >=stealth, line cap=round] (-1.5, 0.0) -- (1.5, 0,0);
    \begin{axis}[x=1cm, y=1cm, ticks=none, axis lines=none, colormap/hot, anchor=origin,
    trig format plots=rad, domain=0.1:1, variable=t, point meta=t,
    ]
        \def\helixX{{t*sin(4.5*t*pi)}}
        \def\helixY{{-t*cos(4.5*t*pi)}}
        \addplot[mesh, line cap=round,samples=51,ultra thick,shader=interp] 
            (\helixX,\helixY);

        \addplot[samples=35,draw=none] 
            (\helixX,\helixY)
            [arrow inside={end=stealth,opt={mapped color!50!black, scale=1.05}}{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9}]
        ;
    \end{axis}
\end{tikzpicture} 
\end{document}

enter image description here

  • Thanks for your solution. Do you think it is possible that the arrow tips have the same color as the line, i.e. that the also exhibit a color gradient? – Daniel Dec 2 '14 at 21:40
  • Ah - I must have misunderstood your request. I will look into the additional request when I find time. – Christian Feuersänger Dec 3 '14 at 18:59
  • thanks for your efforts. I'll also let you know if I find a solution. – Daniel Dec 3 '14 at 23:34
  • I have edited the answer. – Christian Feuersänger Dec 13 '14 at 19:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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