2

I have coloured some paths in a radial drawing of a network graph with a colour gradient. A picture of my document compiled in January 2020 shows what it should look like:

enter image description here

To achieve this effect I have used How do I use spath3 package to shading a path?. The original question can be found here: Tikz: Shading a path without any filling

In the last months I have not compiled this document but made the mistake to update my LaTeX installation. Now when I compile it, I get (in debug mode showing node ids and edge ids instead of labels):

enter image description here

As you can see edge e007 has the same shape as e002 but this should not be the case. From my understanding the first path with style fade no fill is copied to all other paths.

I do not want to share my full document but I think following MWE using fade-no-fill.sty illustrates it as well:

\documentclass[tikz,border=5mm]{standalone}
\usepackage{fade-no-fill}
% rputover {{{1
% –––––––––––––––––
% https://tex.stackexchange.com/a/457885/8917
\makeatletter
\tikzset{
  use path/.code={\pgfsyssoftpath@setcurrentpath{#1}}
}
\makeatother

\tikzset{remember path/.style={save path=\tmprotect}}
\tikzset{reverseclip/.style={insert path={(current bounding box.north
        east) rectangle (current bounding box.south west)}}%
}
\begin{document}
\begin{tikzpicture}

    % PATH 1

    \draw (0cm,-2cm) -- (1cm,0cm);

    % PATH 2
  \begin{scope}

    \node[remember path,font=\Large\sf] at (0.5cm,-1cm) {label};
    \clip[use path=\tmprotect,reverseclip];

    % PATH 2
    \path[
      % draw=blue,
      fade path but don't fill={ very thick, transparent!20, ->, }{top color=blue!80, bottom color=green!80,},
    ] (0cm,0cm) .. controls +(0cm,-1cm) and +(0cm,1cm) .. (1cm,-2cm);

    % PATH 3
  \end{scope}
    \path[
      % draw=red,
      fade path but don't fill={ very thick, transparent!20, ->, }{ top color=blue!80, bottom color=green!80, },
    ] (1cm,1cm) -- (2cm,-1cm);

  % PATH 4
    \draw (-3cm,-2cm) -- (1cm,0cm);

\end{tikzpicture}
\end{document}

which gives the result without fade no fill:
enter image description here

and with fade no fill:
enter image description here

Again the second path becomes surprisingly a bezier curve which actually is a straight line

Does someone know what package has changed and how to solve it? Package spath3 seems to be unchanged since the beginning of 2019. I guess something with pgf/tikz has changed.

2
  • 2
    It is the same problem as here tex.stackexchange.com/questions/566539/…. The code is reusing a fading name tempfade for all fadings but this no longer works. Some counter must be added to get unique names. Oct 15 '20 at 15:45
  • Thank you. Yes, that solved the problem. I will post a my modified fade-no-fill.sty based on your suggestion, if you do not mind.
    – Hotschke
    Oct 16 '20 at 6:09
3

This answer is using the suggestion from Ulrike Fischer in the comments to the question:

Modified fade-no-fill.sty:

%\url{https://tex.stackexchange.com/a/327713/86}
\usetikzlibrary{math}%
\usetikzlibrary{fadings}%
\usepackage{spath3}
\usetikzlibrary{arrows.meta}% needed so that bounding boxes correctly include arrows.

\ExplSyntaxOn
\cs_if_exist:NF \spath_set_current_softpath:n {

\cs_new_protected_nopar:Npn \spath_set_current_softpath:n #1
{
  \spath_get:nnN {#1} {min bb} \l__spath_tmpa_tl
  \exp_last_unbraced:NV \pgf@protocolsizes\l__spath_tmpa_tl

  \spath_get:nnN {#1} {max bb} \l__spath_tmpa_tl
  \exp_last_unbraced:NV \pgf@protocolsizes\l__spath_tmpa_tl

  \spath_get:nnN {#1} {path} \l__spath_tmpa_tl
  \pgfsyssoftpath@setcurrentpath\l__spath_tmpa_tl
}
}
\tikzset{restore~ soft~ path/.code={%
    \spath_set_current_softpath:n {#1}
  }
}
\ExplSyntaxOff

\makeatletter
\newcount\pgf@fadingboxcnt
\tikzset{
  fade path but don't fill/.style 2 args={
    preaction={save spath=fadingpath,},
    postaction={
      /utils/exec={
        \coordinate (oldbb-ne) at (current bounding box.north east);
        \coordinate (oldbb-sw) at (current bounding box.south west);
        \pgfresetboundingbox
        \global\advance \pgf@fadingboxcnt by 1
        \begin{tikzfadingfrompicture}[name=tempfade\the\pgf@fadingboxcnt]%
        \pgfresetboundingbox
        \draw[restore soft path=fadingpath,#1];
        \coordinate (temp-fade-bb-ne) at (current bounding box.north east);
        \coordinate (temp-fade-bb-sw) at (current bounding box.south west);
        \coordinate (temp-fade-bb-center) at (current bounding box.center);
        \end{tikzfadingfrompicture}
        %
        \useasboundingbox (oldbb-ne) rectangle (oldbb-sw);
        %
        \tikzmath{
          coordinate \ctempfadebbcenter;
          \ctempfadebbcenter = (temp-fade-bb-center);
        }
        \tikzset{tempstyle/.style/.expand once={#2}}
        \path[
          path fading=tempfade\the\pgf@fadingboxcnt,
          fit fading=false,
          fading transform={
            yshift=\ctempfadebbcentery,
            xshift=\ctempfadebbcenterx,
          },
          tempstyle,
        ] (temp-fade-bb-ne) rectangle (temp-fade-bb-sw);
      },
    },
  },
}
\makeatother

With the modified fade-no-fill.sty the posted MWE gives the expected result:

enter image description here


Updated 2021-07-13 by Andrew Stacey: Since the previous version of fade-no-fill.sty was written then the spath3 library has undergone a considerable update. The following is a version of fade-no-fill.sty that incorporates the solution to this question with the updates to use the latest version of spath3:

%\url{https://tex.stackexchange.com/a/327713/86}
\usetikzlibrary{math}%
\usetikzlibrary{fadings}%
\usetikzlibrary{spath3}
\usetikzlibrary{arrows.meta}% needed so that bounding boxes correctly include arrows.

\newcount\pgf@fadingboxcnt
\tikzset{
  fade path but don't fill/.style 2 args={
    preaction={spath/save global=fadingpath,},
    postaction={
      /utils/exec={
        \coordinate (oldbb-ne) at (current bounding box.north east);
        \coordinate (oldbb-sw) at (current bounding box.south west);
        \pgfresetboundingbox
        \global\advance \pgf@fadingboxcnt by 1\relax
        \begin{tikzfadingfrompicture}[name=tempfade\the\pgf@fadingboxcnt]%
        \pgfresetboundingbox
        \draw[spath/use=fadingpath,#1];
        \coordinate (temp-fade-bb-ne) at (current bounding box.north east);
        \coordinate (temp-fade-bb-sw) at (current bounding box.south west);
        \coordinate (temp-fade-bb-center) at (current bounding box.center);
        \end{tikzfadingfrompicture}
        %
        \useasboundingbox (oldbb-ne) rectangle (oldbb-sw);
        %
        \tikzmath{
          coordinate \ctempfadebbcenter;
          \ctempfadebbcenter = (temp-fade-bb-center);
        }
        \tikzset{tempstyle/.style/.expand once={#2}}
        \path[
          path fading=tempfade\the\pgf@fadingboxcnt,
          fit fading=false,
          fading transform={
            yshift=\ctempfadebbcentery,
            xshift=\ctempfadebbcenterx,
          },
          tempstyle,
        ] (temp-fade-bb-ne) rectangle (temp-fade-bb-sw);
      },
    },
  },
}

I'm adding it to this answer rather than putting it as a separate answer because it doesn't bring anything new to this particular question, and I'm not changing the original code because at time of writing then it is still plausible that there are installations with the old version of spath3.

1
  • I've added a version of the fade-no-fill style file that uses the most recent version of spath3. I hope that was okay to add it to your answer rather than post it separately. Jul 13 at 20:33

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.