[Tex/LaTex] Scale dash pattern with line width

tikz-pgftikz-styles

I would like to have dash patterns which scale proportionally to the active line width like shown in the following example:

\documentclass[tikz]{standalone}
\newdimen\gpdashlength
\begin{document}

\begin{tikzpicture}
\pgfsetlinewidth{2pt}
\gpdashlength=0.5\pgflinewidth
\tikzset{gp path/.style={dash pattern=on 7.5\gpdashlength off 7.5\gpdashlength}}

\draw[gp path] (1.012,3.528)--(11.947,5.469);

\pgfsetlinewidth{4pt}
\gpdashlength=0.5\pgflinewidth
\draw[gp path] (1.012,2.557)--(11.947,6.440);
\end{tikzpicture}
\end{document}

enter image description here

This works fine, but I would like to set some property of gp path once, so that it always selects the current line width scaled by some factor. I tried using gp path/.code, but that has no effect. The following document doesn't show anything:

\documentclass[tikz]{standalone}
\newdimen\gpdashlength
\begin{document}

\begin{tikzpicture}
\tikzset{gp path/.code={\gpdashlength=0.5\pgflinewidth},
         gp path/.style={dash pattern=on 7.5\gpdashlength off 7.5\gpdashlength}}

\pgfsetlinewidth{2pt}
\draw[gp path] (1.012,3.528)--(11.947,5.469);

\pgfsetlinewidth{4pt}
\draw[gp path] (1.012,2.557)--(11.947,6.440);
\end{tikzpicture}
\end{document}

It seems to me like the .code part is executed after the .style so that \gpdashlength isn't set properly.

Whats wrong with the second example?

Note that this is supposed to be used for gnuplot's lua tikz terminal, so an overall restructuring of the example may not be possible. That means, that the \pgflinewidth cannot be contained in the dash pattern definition, since this is located in a system-wide style file, and the scaling factor between the line width and the dash pattern can be changed from document to document.

Best Answer

The problem is that \gpdashlength is a length, not a macro, and then it is not expanded, but replaced by a length value. So, if you want to change that value, an assignment has to be made before the length is evaluated, and you cannot do it inside .code key because, as you guessed, it is not executed before evaluating the style.

A solution is to change \gpdashlength from a lengt to a macro, i.e:

\def\gpdashlength{0.5*\pgflinewidth}

This way, when this macro is found as part of the dash pattern, it is expanded, so the current value of \pgflinewidth is used at that point. You have to change the dash pattern to include the multiplication sign (*) before \gpdashlength. I.e:

\documentclass[tikz]{standalone}
\begin{document}

\def\gpdashlength{0.5*\pgflinewidth}
\begin{tikzpicture}
\tikzset{
         gp path/.style={dash pattern=on 7.5*\gpdashlength
                                     off 7.5*\gpdashlength}}

\draw[thin, gp path] (1.012,3.528)--(11.947,5.469);
\draw[very thick, gp path] (1.012,2.557)--(11.947,6.440);
\end{tikzpicture}
\end{document}

Which produces:

Result

Note that this works because tikz parses the mathematical expression containing *. That is, after all expansions are performed, tikz "sees" the following dash pattern (assuming that, for example, \pgflinewidth is 0.8pt in this example):

 dash pattern=on 7.5*0.5*0.8pt off 7.5*0.5*0.8pt

Tikz parser is able to evaluate that product. Otherwise this won't work. You cannot generally change a length register by a macro as I did here.