8

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?

2
  • 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, 2014 at 14:33
  • You may want to have a look to Path following color gradient in TikZ. Dec 2, 2014 at 14:36

1 Answer 1

6

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

4
  • 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, 2014 at 21:40
  • Ah - I must have misunderstood your request. I will look into the additional request when I find time. Dec 3, 2014 at 18:59
  • thanks for your efforts. I'll also let you know if I find a solution.
    – Daniel
    Dec 3, 2014 at 23:34
  • I have edited the answer. Dec 13, 2014 at 19:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .