8

I'm having trouble figuring out how I am supposed to combine (or if I am supposed not to combine) pics, clipping and layering when more than one instance of a pic is included in a single tikzpicture environment.

For example:

\documentclass[tikz, border=5pt]{standalone}
\usetikzlibrary{backgrounds}
\makeatletter
  \tikzset{%
    my thing/.pic={
        \draw [line width=2.5pt, gray] (0,10pt) coordinate (c1) [out=45, in=135] to +(1,2) coordinate (c2);
      \begin{scope}[on background layer]
        \clip (0,5) rectangle (5,-5);
        \draw [orange, line width=2.5pt] (-2,0) -| (c2) -| (2,-2);
      \end{scope}
    },
  }
\makeatother
\begin{document}
  \begin{tikzpicture}
    \pic {my thing};
    \pic at (3,3) {my thing};
  \end{tikzpicture}
\end{document}

produces

problematic clippings

Clearly things are not working quite right. I assume that the clipping from one instance of my thing is somehow affecting the clipping in the second instance. But I'm not sure if that is because

  1. I'm doing something wrong and, if so what;
  2. I'm misusing pics (or clips or layers);
  3. this is related to the known bugs with pics;
  4. this is related to another bug in pics;
  5. something I haven't thought of yet.

If 1 or 2, then:

  • Am I making a mistake and, if so, what? Am I misusing something and, if so, what, how and why?

If 3 or 4, then:

  • Oh dear. Is there a workaround and, if there is, what is it?

If 5, then:

  • Please could you explain that?

Note that obviously the clipping and layering and so on above is gratuitous. However, my real use case has led me to produce cats which are unexpectedly reminiscent of Carroll's Cheshire variety:

partial cats

So you can see that the problem is one of the utmost seriousness...

cat's grin?

  • have you reported this bug ? I don't mean the missing cat ;) Great work ! – Kpym Dec 17 '14 at 15:10
  • @Kpym I'm not sure whether it is a bug, and I can't tell from Mark Wibrow's comments on his answer either. So I haven't actually done any work, great or otherwise ;). [You're not concerned about the missing cat? Shame on you!] – cfr Dec 17 '14 at 15:27
6

I think the problem is the order in which the scope is set up and the layer changed to the background layer (although I am not sure of the low level details).

When using the on background layer key the scope is set up and the the layer changed. What is required is the reverse: the layer changed and then the scope set up. This might be a bug, unless there is some caveat hidden in the documentation somewhere, but in the first case, the clipping seems to stay active on the background layer.

The solution is to either add an extra scope inside the other scope with the on background layer option, or to explicitly change the layer and add the scope inside, which is what I have done below.

For clarity I also show the bounding boxes of the clipping region.

\documentclass[tikz, border=5pt]{standalone}
\usetikzlibrary{backgrounds}
\makeatletter
  \tikzset{%
    my thing/.pic={
        \draw [line width=2.5pt, gray] (0,10pt) coordinate (c1) [out=45, in=135] to +(1,2) coordinate (c2);
      \begin{pgfonlayer}{background}
        \begin{scope}
        \clip [preaction=draw] (0,5) rectangle (5,-5);
        \draw [orange, line width=2.5pt] (-2,0) -| (c2) -| (2,-2);
        \end{scope}
      \end{pgfonlayer}
    },
  }
\makeatother
\begin{document}
  \begin{tikzpicture}
    \pic {my thing};
    \pic at (3,3) {my thing};
  \end{tikzpicture}
\end{document}

enter image description here

  • 1
    As usual you are right. But is this a bug ? That is not clear for me. How can we use a style to execute the code before and after the current scope ? For me this is a really missing feature in tikz : having a key handler like .code before scope and .code after scope. In this case we can have style on background that execute before the scopepgfonlayer and after the scope endpgfonlayer. – Kpym Dec 16 '14 at 14:14
  • Thanks! It would be good to know if there is a bug and/or if there is a way to wrap these moves into the style on background. – cfr Dec 16 '14 at 16:53
  • Since on background layer is a style that just uses the execute at begin scope and execute at end scope keys it should be simple to define an appropriate style based on the definition in tikzlibrarybackgrounds.code.tex – Mark Wibrow Dec 16 '14 at 17:36
  • @Mark Wibrow oh, you meant to add another supplementary scope, not to use the original on ? This is simpler than my proposition. But still, I think that there is missing in TikZ a good hook system. For example we don't have .execute at begin/end path, .execute before begin/after end path, .execute at begin/end node/pic, ... – Kpym Dec 16 '14 at 21:52
  • I can't yet figure out how to wrap this up neatly (or how to do it by adding an additional scope), but the explicit layer change works well - just feels a bit clumsy since I have to do this multiple times within the pic. – cfr Dec 27 '14 at 16:04

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.