2

I want to save a plot, draw it cropped and put an arrow on it

\documentclass[10pt,convert={convertexe=magick,density=1000,outext=.png}]{standalone}

\usepackage{tikz,pgfplots} \usetikzlibrary{decorations.markings}

\begin{document}

\begin{tikzpicture}

\begin{axis} \addplot[save path=\test] coordinates {(0,0) (2,3) (5,5)};

\begin{scope} \clip (axis cs:1,1) rectangle (axis cs:4,4); % \draw[red][use path=\test]; % <-- THIS WORKS \draw[red,postaction={decorate},decoration={markings,mark=at position 0.5 with {\arrow{stealth}}}][use path=\test]; \end{scope}

\end{axis} \end{tikzpicture}

\end{document}

Well, putting arrow does not work, because I get the message

! Package pgf Error: I cannot decorate an empty path.

What is a workaround for this problem?

The solution provided here does not work

enter image description here

Pygmalion
  • 6,387
  • 4
  • 34
  • 68

2 Answers2

4

Maybe the easiest way is just to use another \addplot using the same coordinate list to add the marking after having drawn the red clipped line. You could store the coordinates inside a table for easy access:

\documentclass[10pt]{standalone}

\usepackage{tikz,pgfplots} \usetikzlibrary{decorations.markings}

\pgfplotstableread[row sep=crcr]{ 0 0 \ 2 3 \ 5 5 \ }\plotcoords

\begin{document}

\begin{tikzpicture}

\begin{axis} \addplot[save path=\test, draw=none] table {\plotcoords};

\begin{scope} \clip (axis cs:1,1) rectangle (axis cs:4,4); \draw[red][use path=\test];
\end{scope}

\addplot[draw=none, postaction={decorate}, decoration={markings,mark=at position 0.5 with {\arrow{stealth}}}] table {\plotcoords};

\end{axis} \end{tikzpicture}

\end{document}

enter image description here

2

Mixing pgfplots and tikz has a few unforeseen hitches that can catch out the unwary.

The first is that \addplot doesn't render its path at the invocation time but rather it gets saved up for the end of the axis environment. So a path defined by \addplot is not available until after the axis environment ends. Fortunately, a pgfplots axis also affects normal TikZ \draw (and similar) commands so these also get gathered up and dealt with at the end of the axis environment. So you don't notice this in your situation, but it is worth knowing about.

The second is that \addplot also introduces lots of scopes, which introduce TeX groups, and so things that are defined locally don't last out of their groups. So the spath/save from the previous answer needs to be replaced by spath/save global to make the path global.

The third is that \addplot takes its key values by default in the pgfplots directory. So the spath key needs to have its absolute path and be invoked as /tikz/spath/save global.

\documentclass[10pt,convert={convertexe=magick,density=1000,outext=.png}]{standalone}
%\url{https://tex.stackexchange.com/q/650703/86}
\usepackage{tikz,pgfplots}
\usetikzlibrary{decorations.markings,spath3}

\tikzset{ message/.code={\message{this is message #1^^J}} }

\begin{document}

\begin{tikzpicture}

\begin{axis} \addplot[/tikz/message=one,/tikz/spath/save global=test] coordinates {(0,0) (2,3) (5,5)};

\tikzset{message=two,spath/show=test} % path doesn't exist here

\begin{scope} \clip (axis cs:1,1) rectangle (axis cs:4,4); \draw[message=three,ultra thick, red,postaction={decorate},decoration={markings,mark=at position 0.5 with {\arrow{stealth}}}][spath/use=test]; \end{scope}

\tikzset{message=four}

\end{axis} \end{tikzpicture}

\end{document}

The message key is included in the above to show how the order of things happens. In the code, there are four messages in the order one, two, three, and four. In the logfile, it produces:

this is message one
this is message two

Package spath3 Warning: Soft path test doesn't exist on line 17

this is message four this is message one this is message three

Note also that the test path doesn't exist when it is "shown" in the \tikzset line. It doesn't get defined until the end of the axis environment.

Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751