13

I have always wondered whether it was possible to define some sort of "relative" transparency in TikZ. What do I mean?

Sometimes, you want a node to be filled in order for its content to be readable among lines and shapes. Now, imagine you have a TikZ picture on some shaded background. It would be great if one could specify that the node should be opaque with respect to the rest of the picture (or the scope), but stay transparent with respect to the background defined outside.

\documentclass{article}

\usepackage{framed,xcolor,tikz}
\definecolor{shadecolor}{gray}{.85}

\begin{document}

\begin{shaded}
   \begin{tikzpicture}
      \draw (0,0) --node[fill=shadecolor] {a} (5,0);
   \end{tikzpicture}
\end{shaded}

\end{document}

In the above situation, it is possible to use shadecolor, because this is how the shaded environment works. I would like to know whether a more general solution exists, e.g. one that works in situations where you cannot find out the background color of the surrounding environment.

Updated information

I will try to state things a bit clearer. I often use TikZ for geometric figures and/or plots. Then, sometimes you have lines running through a coordinate label. In most cases, it is enough to slightly change the figure, e.g. by moving the label to a different anchor or even adapt some angle and thus have the line just miss the label.

However, in some cases, there is no other way than to put the label in a filled node with an inner sep of 1 or 2 points, so that it stands out among all other stuff. The main problem is that I have to use the background color to fill my node, normally this is white, but sometimes it might be some gray color.

The example I included is very easy, just to illustrate the problem. In this simple case, I could, of course, just draw the line in two pieces. In a normal use case, this is not possible.

So another way of saying it: I would love to draw the figure just as if there was a white background, using fill=white for such nodes. And then, after all is finished, I could say that all white stuff becomes transparent, so that the gray (or whatever) background shines through.

Using percusse's solution with transparency groups, it is not possible to achieve what I am looking for. The whole scope becomes partially transparent, so the line is not black anymore and the background is still lightened up. I would want the line to stay completely black and the node fill to be completely invisible.

enter image description here

2 Answers 2

2

I just had a similar question marked as a duplicate of this one. Here is the link. Unfortunately, the answer posted here was not marked as an answer and OP indicated it as not working. Credit for this approach goes to @symbol-1.

As noted by @percusse here and @cfr and @symbol-1 in the link, the result will be viewer dependent. Examples of viewer differences provided below the code.

Here is modified from the OP and @percusse's answer using transparency group=knockout in the scope environment options:

\documentclass[tikz]{standalone}
\usetikzlibrary{patterns}

\begin{document}

\begin{tikzpicture}
    \path[pattern=crosshatch dots light steel blue](-2,-2) rectangle (2,2);
    \begin{scope}[transparency group=knockout]
        \draw (-2,0) to node(aaaaa){} (2,0);
        \path (aaaaa) node[fill,opacity=0,text opacity=1]{aaaaa};
    \end{scope}
\end{tikzpicture}

\end{document}

You can change the background to anything you like and no other changes are necessary. If you change the text to be longer/short, the background opacity will resize accordingly - i.e. no changes other than the label name.

In some PDF viewers (e.g. SumatraPDF, TeXworks previewer, etc.): Result of non-conforming PDF viewers

In other PDF viewers (e.g. Adobe Acrobat): Result of conforming PDF viewers

The PDF is the same in both cases. I simply took a screenshot of it opened in two different PDF viewers. It seems the background is affected as well, but the focus here is the transparency.

Also, here is an example of an additional node with text going vertically to illustrate what happens with transparency group=knockout with multiple nodes:

\documentclass[tikz]{standalone}
\usetikzlibrary{patterns}

\begin{document}

\begin{tikzpicture}
    \path[pattern=crosshatch dots light steel blue](-2,-2) rectangle (2,2);
    \begin{scope}[transparency group=knockout]
        \draw (-2,0) to node(aaaaa){} (2,0);
        \path (aaaaa) node[fill,opacity=0,text opacity=1]{aaaaa};
        \draw (0,-2) to node(bbbbb){} (0,2);
        \path (bbbbb) node[fill,opacity=0,text opacity=1]{\rotatebox[origin=c]{90}{bbbbb}};
        \draw (-2,-0.35) to node(ccccc){} (2,-0.35);
        \path (ccccc) node[fill=red,text opacity=1]{ccccc};
    \end{scope}
\end{tikzpicture}

In some PDF viewers (e.g. SumatraPDF, TeXworks previewer, etc.): Result of second example in non-conforming PDF viewers

In other PDF viewers (e.g. Adobe Acrobat): Result of second example in conforming PDF viewers

You will notice that whichever item is last with opacity=0 takes precedence over the previous item(s). If you flip the aaaaa and bbbbb lines and nodes (i.e bbbbb occurs first), for example, you'll see this (in the conforming PDF viewers): Result of third example in conforming PDF viewers

opacity=0 also takes precedence over other items which do not have opacity. For example, if we move the ccccc node/lines first within the tikzpicture, here is the result: Result of fourth example in conforming PDF viewers

Just remember! If your picture is very complicated and you open it in an old or (transparency) non-conforming PDF viewer, it will not be what you expect.

If you have many nodes with transparency and you do not like the overlapping issue, you will need to adjust the order of the nodes, xshift and yshift, and/or place the nodes in different positions completely.

19

This is done via transparency groups and relies mostly on PDF rendering so sometimes it might go awry. Here is an example that within the scope everything is as usual overprinting with respect to drawing order but the overall result is transparent with respect to the background.

\documentclass[tikz]{standalone}
\usetikzlibrary{patterns}
\begin{document}
\begin{tikzpicture}
\path[pattern=crosshatch dots light steel blue](-2,-2) rectangle (2,2);
\begin{scope}[transparency group,opacity=.6]
\node[fill=yellow] {Heeeeeeeeeeeeeeeeeeey!};
\node[align=center,fill,circle,text=white] {Transparent\\ but overpaints\\ the rectangle};
\end{scope}
\end{tikzpicture} 
\end{document}

enter image description here

6
  • Thank you for the idea, I missed that in the manual. However, I cannot see how to solve the initial issue with this, maybe I misunderstood your solution: the fill of the node should be fully opaque w.r.t. the line, but fully transparent w.r.t. the background defined outside of tikzpicture. With a transparency group, the background will still lighten up and the line would be 100% black. Aug 30, 2015 at 17:36
  • @PhilippImhof I don't understand the line example in your description. If you make the whole TikZ picture a transparency group then it would be transparent with respect to the page no? Do you mind making a visual example with more elements?
    – percusse
    Aug 30, 2015 at 22:45
  • I updated the description. If the transparency group becomes transparent with respect to the page, it becomes invisible. Transparency will apply to all group members. However, I would want the line to remain black. The node fill should become transparent, but still cover (interrupt) the line. Aug 31, 2015 at 4:21
  • @PhilippImhof A painted pixel can't be "unpainted"... Aug 31, 2015 at 5:19
  • 1
    @PhilippImhof I think now I'm starting to understand your point. Let me think about it for a while. But in any case it would require a very very recent viewer and printer to be useful. Because these are pretty recent specifications in PDF standards >v1.7
    – percusse
    Aug 31, 2015 at 20:14

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.