LaTeX TikZ Colorful Background Layer

Aug. 11, 2024

pgfonlayer environment

There’s an example, A Petri-net for Hagen, on TeXample.net1 and TikZ & PGF Manual2:

png-1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
% Author: Till Tantau
% Source: The PGF/TikZ manual
\documentclass{standalone}
\standaloneconfig{border=1em}

\def\xcolorversion{2.00}
\def\xkeyvalversion{1.8}

\usepackage[version=0.96]{pgf}
\usepackage{tikz}
\usetikzlibrary{arrows,shapes,snakes,automata,backgrounds,petri}
\usepackage[latin1]{inputenc}
\begin{document}

\begin{tikzpicture}[node distance=1.3cm,>=stealth',bend angle=45,auto]
  \tikzstyle{place}=[circle,thick,draw=blue!75,fill=blue!20,minimum size=6mm]
  \tikzstyle{red place}=[place,draw=red!75,fill=red!20]
  \tikzstyle{transition}=[rectangle,thick,draw=black!75,
  			  fill=black!20,minimum size=4mm]

  \tikzstyle{every label}=[red]

  \begin{scope}
    % First net
    \node [place,tokens=1] (w1)                                    {};
    \node [place] (c1) [below of=w1]                      {};
    \node [place] (s)  [below of=c1,label=above:$s\le 3$] {};
    \node [place] (c2) [below of=s]                       {};
    \node [place,tokens=1] (w2) [below of=c2]                      {};

    \node [transition] (e1) [left of=c1] {}
      edge [pre,bend left]                  (w1)
      edge [post,bend right]                (s)
      edge [post]                           (c1);

    \node [transition] (e2) [left of=c2] {}
      edge [pre,bend right]                 (w2)
      edge [post,bend left]                 (s)
      edge [post]                           (c2);

    \node [transition] (l1) [right of=c1] {}
      edge [pre]                            (c1)
      edge [pre,bend left]                  (s)
      edge [post,bend right] node[swap] {2} (w1);

    \node [transition] (l2) [right of=c2] {}
      edge [pre]                            (c2)
      edge [pre,bend right]                 (s)
      edge [post,bend left]  node {2}       (w2);
  \end{scope}

  \begin{scope}[xshift=6cm]
    % Second net
    \node [place,tokens=1]
                      (w1')                                                {};
    \node [place]     (c1') [below of=w1']                                 {};
    \node [red place] (s1') [below of=c1',xshift=-5mm,label=left:$s$]      {};
    \node [red place,tokens=3]
                      (s2') [below of=c1',xshift=5mm,label=right:$\bar s$] {};
    \node [place]     (c2') [below of=s1',xshift=5mm]                      {};
    \node [place,tokens=1]
                      (w2') [below of=c2']                                 {};

    \node [transition] (e1') [left of=c1'] {}
      edge [pre,bend left]                  (w1')
      edge [post]                           (s1')
      edge [pre]                            (s2')
      edge [post]                           (c1');

    \node [transition] (e2') [left of=c2'] {}
      edge [pre,bend right]                 (w2')
      edge [post]                           (s1')
      edge [pre]                            (s2')
      edge [post]                           (c2');

    \node [transition] (l1') [right of=c1'] {}
      edge [pre]                            (c1')
      edge [pre]                            (s1')
      edge [post]                           (s2')
      edge [post,bend right] node[swap] {2} (w1');

    \node [transition] (l2') [right of=c2'] {}
      edge [pre]                            (c2')
      edge [pre]                            (s1')
      edge [post]                           (s2')
      edge [post,bend left]  node {2}       (w2');
  \end{scope}

  \draw [-to,thick,snake=snake,segment amplitude=.4mm,
         segment length=2mm,line after snake=1mm]
    ([xshift=5mm]s -| l1) -- ([xshift=-5mm]s1' -| e1')
    node [above=1mm,midway,text width=3cm,text centered]
      {replacement of the \textcolor{red}{capacity} by 
        \textcolor{red}{two places}};

  \begin{pgfonlayer}{background}
    \filldraw [line width=4mm,join=round,black!10]
      (w1.north  -| l1.east)  rectangle (w2.south  -| e1.west)
      (w1'.north -| l1'.east) rectangle (w2'.south -| e1'.west);
  \end{pgfonlayer}
\end{tikzpicture}

\end{document}

In this example, two parts of graphs are respectively put in two scope environments in tikzpicture.

scope environment3

1
2
3
\begin{scope}<animations spec>[<options>]
	<environment contents>
\end{scope}

All <options> are local to the <environment contents>. Furthermore, the clipping path is also local to the environment, that is, any clipping done inside the environment “ends” at its end.

Then, two gray backgrounds are created and put underneath above two graphs by following code:

1
2
3
4
5
\begin{pgfonlayer}{background}
    \filldraw [line width=4mm,join=round,black!10]
    (w1.north  -| l1.east)  rectangle (w2.south  -| e1.west)
    (w1'.north -| l1'.east) rectangle (w2'.south -| e1'.west);
\end{pgfonlayer}

Actually, these two backgrounds are two blank but gray layers created by pgfonlayer environment:

113.3 Using Layers4

Once the layers of your picture have been declared, you can start to “fill” them. As said before, all graphics commands are normally added to the main layer. Using the {pgfonlayer} environment, you can tell pgf that certain commands should, instead, be added to the given layer.

1
2
3
\begin{pgfonlayer}{<layer name>}
	<environment contents>
\end{pgfonlayer}

The whole <environment contents> is added to the layer with the name <layer name>. This environment can be used anywhere inside a picture. Thus, even if it is used inside a {pgfscope} or a TeX group, the contents will still be added to the “whole” picture. Using this environment multiple times inside the same picture will cause the <environment contents> to accumulate.

Note: You can not add anything to the main layer using this environment. The only way to add anything to the main layer is to give graphic commands outside all {pgfonlayer} environments.

\filldraw5: Inside {tikzpicture} this is an abbreviation for \path[fill,draw].

The use of -| is artful, and relevant information can be found in6.

By the way, TikZ library backgrounds is needed:

1
\usetikzlibrary{...,backgrounds,...}


\tikzset command

If we want to specify a background for the whole tikzpicture, referring to documentation7 , we can use \tikzset command to set a background rectangle (15th line in the following code), and add the framed option (that is a shorthand for show background rectangle.8) to tikzpicture environment (16th line). TikZ library backgrounds is also necessary in this case.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
% Author: Till Tantau
% Source: The PGF/TikZ manual
\documentclass{standalone}
\standaloneconfig{border=1em}

\def\xcolorversion{2.00}
\def\xkeyvalversion{1.8}

\usepackage[version=0.96]{pgf}
\usepackage{tikz}
\usetikzlibrary{arrows,shapes,snakes,automata,backgrounds,petri}
\usepackage[latin1]{inputenc}
\begin{document}

\tikzset{background rectangle/.style={rounded corners,fill=blue!20}}
\begin{tikzpicture}[framed,node distance=1.3cm,>=stealth',bend angle=45,auto]
  \tikzstyle{place}=[circle,thick,draw=blue!75,fill=blue!20,minimum size=6mm]
  \tikzstyle{red place}=[place,draw=red!75,fill=red!20]
  \tikzstyle{transition}=[rectangle,thick,draw=black!75,
  			  fill=black!20,minimum size=4mm]

  \tikzstyle{every label}=[red]

  \begin{scope}
    % First net
    \node [place,tokens=1] (w1)                                    {};
    \node [place] (c1) [below of=w1]                      {};
    \node [place] (s)  [below of=c1,label=above:$s\le 3$] {};
    \node [place] (c2) [below of=s]                       {};
    \node [place,tokens=1] (w2) [below of=c2]                      {};

    \node [transition] (e1) [left of=c1] {}
      edge [pre,bend left]                  (w1)
      edge [post,bend right]                (s)
      edge [post]                           (c1);

    \node [transition] (e2) [left of=c2] {}
      edge [pre,bend right]                 (w2)
      edge [post,bend left]                 (s)
      edge [post]                           (c2);

    \node [transition] (l1) [right of=c1] {}
      edge [pre]                            (c1)
      edge [pre,bend left]                  (s)
      edge [post,bend right] node[swap] {2} (w1);

    \node [transition] (l2) [right of=c2] {}
      edge [pre]                            (c2)
      edge [pre,bend right]                 (s)
      edge [post,bend left]  node {2}       (w2);
  \end{scope}

  \begin{scope}[xshift=6cm]
    % Second net
    \node [place,tokens=1]
                      (w1')                                                {};
    \node [place]     (c1') [below of=w1']                                 {};
    \node [red place] (s1') [below of=c1',xshift=-5mm,label=left:$s$]      {};
    \node [red place,tokens=3]
                      (s2') [below of=c1',xshift=5mm,label=right:$\bar s$] {};
    \node [place]     (c2') [below of=s1',xshift=5mm]                      {};
    \node [place,tokens=1]
                      (w2') [below of=c2']                                 {};

    \node [transition] (e1') [left of=c1'] {}
      edge [pre,bend left]                  (w1')
      edge [post]                           (s1')
      edge [pre]                            (s2')
      edge [post]                           (c1');

    \node [transition] (e2') [left of=c2'] {}
      edge [pre,bend right]                 (w2')
      edge [post]                           (s1')
      edge [pre]                            (s2')
      edge [post]                           (c2');

    \node [transition] (l1') [right of=c1'] {}
      edge [pre]                            (c1')
      edge [pre]                            (s1')
      edge [post]                           (s2')
      edge [post,bend right] node[swap] {2} (w1');

    \node [transition] (l2') [right of=c2'] {}
      edge [pre]                            (c2')
      edge [pre]                            (s1')
      edge [post]                           (s2')
      edge [post,bend left]  node {2}       (w2');
  \end{scope}

  \draw [-to,thick,snake=snake,segment amplitude=.4mm,
         segment length=2mm,line after snake=1mm]
    ([xshift=5mm]s -| l1) -- ([xshift=-5mm]s1' -| e1')
    node [above=1mm,midway,text width=3cm,text centered]
      {replacement of the \textcolor{red}{capacity} by 
        \textcolor{red}{two places}};

  \begin{pgfonlayer}{background}
    \filldraw [line width=4mm,join=round,black!10]
      (w1.north  -| l1.east)  rectangle (w2.south  -| e1.west)
      (w1'.north -| l1'.east) rectangle (w2'.south -| e1'.west);
  \end{pgfonlayer}
\end{tikzpicture}

\end{document}

png-1

However, as can be seen, the newly added background lays on the middle of main layer and background layer, covering the latter. We can specify opacity of the background rectangle to mitigate it, for example:

1
\tikzset{background rectangle/.style={rounded corners,fill=blue!20,opacity=0.2}}

png-1

We can see the background layer at this time. However, what I exactly want is to make background rectangle be the bottom layer, but I don’t find a way to change layers order in this case.


Specify layers order

To change layers order (refer to4), we can also use pgfonlayer environment to create a whole background (see 102-111th line in the following code), and declare layers name and specify whose order before tikzpicture environment (17th-19th line). The complete code for realization shows as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
% Author: Till Tantau
% Source: The PGF/TikZ manual
\documentclass{standalone}
\standaloneconfig{border=1em}

\def\xcolorversion{2.00}
\def\xkeyvalversion{1.8}

\usepackage[version=0.96]{pgf}
\usepackage{tikz}
\usetikzlibrary{fit}  

\usetikzlibrary{arrows,shapes,snakes,automata,backgrounds,petri}
\usepackage[latin1]{inputenc}
\begin{document}

\pgfdeclarelayer{bg1}
\pgfdeclarelayer{bg2}
\pgfsetlayers{bg2,bg1,main}

\begin{tikzpicture}[node distance=1.3cm,>=stealth',bend angle=45,auto]
  \tikzstyle{place}=[circle,thick,draw=blue!75,fill=blue!20,minimum size=6mm]
  \tikzstyle{red place}=[place,draw=red!75,fill=red!20]
  \tikzstyle{transition}=[rectangle,thick,draw=black!75,
  			  fill=black!20,minimum size=4mm]

  \tikzstyle{every label}=[red]

  \begin{scope}
    % First net
    \node [place,tokens=1] (w1)                                    {};
    \node [place] (c1) [below of=w1]                      {};
    \node [place] (s)  [below of=c1,label=above:$s\le 3$] {};
    \node [place] (c2) [below of=s]                       {};
    \node [place,tokens=1] (w2) [below of=c2]                      {};

    \node [transition] (e1) [left of=c1] {}
      edge [pre,bend left]                  (w1)
      edge [post,bend right]                (s)
      edge [post]                           (c1);

    \node [transition] (e2) [left of=c2] {}
      edge [pre,bend right]                 (w2)
      edge [post,bend left]                 (s)
      edge [post]                           (c2);

    \node [transition] (l1) [right of=c1] {}
      edge [pre]                            (c1)
      edge [pre,bend left]                  (s)
      edge [post,bend right] node[swap] {2} (w1);

    \node [transition] (l2) [right of=c2] {}
      edge [pre]                            (c2)
      edge [pre,bend right]                 (s)
      edge [post,bend left]  node {2}       (w2);
  \end{scope}

  \begin{scope}[xshift=6cm]
    % Second net
    \node [place,tokens=1]
                      (w1')                                                {};
    \node [place]     (c1') [below of=w1']                                 {};
    \node [red place] (s1') [below of=c1',xshift=-5mm,label=left:$s$]      {};
    \node [red place,tokens=3]
                      (s2') [below of=c1',xshift=5mm,label=right:$\bar s$] {};
    \node [place]     (c2') [below of=s1',xshift=5mm]                      {};
    \node [place,tokens=1]
                      (w2') [below of=c2']                                 {};

    \node [transition] (e1') [left of=c1'] {}
      edge [pre,bend left]                  (w1')
      edge [post]                           (s1')
      edge [pre]                            (s2')
      edge [post]                           (c1');

    \node [transition] (e2') [left of=c2'] {}
      edge [pre,bend right]                 (w2')
      edge [post]                           (s1')
      edge [pre]                            (s2')
      edge [post]                           (c2');

    \node [transition] (l1') [right of=c1'] {}
      edge [pre]                            (c1')
      edge [pre]                            (s1')
      edge [post]                           (s2')
      edge [post,bend right] node[swap] {2} (w1');

    \node [transition] (l2') [right of=c2'] {}
      edge [pre]                            (c2')
      edge [pre]                            (s1')
      edge [post]                           (s2')
      edge [post,bend left]  node {2}       (w2');
  \end{scope}

  \draw [-to,thick,snake=snake,segment amplitude=.4mm,
         segment length=2mm,line after snake=1mm]
    ([xshift=5mm]s -| l1) -- ([xshift=-5mm]s1' -| e1')
    node [above=1mm,midway,text width=3cm,text centered]
      {replacement of the \textcolor{red}{capacity} by 
        \textcolor{red}{two places}};

  \begin{pgfonlayer}{bg1}
    \filldraw [line width=4mm,join=round,color=black!10]
      (w1.north  -| l1.east)  rectangle (w2.south  -| e1.west)
      (w1'.north -| l1'.east) rectangle (w2'.south -| e1'.west);
  \end{pgfonlayer}
  
  \begin{pgfonlayer}{bg2} 
      \filldraw [line width=4mm,join=round,color=blue!20]
      (current bounding box.south west) rectangle (current bounding box.north east);
  \end{pgfonlayer}

\end{tikzpicture}
\end{document}

png-1

Which way is more elegant. One point should be particularly noted that how to use relative orientation of current bounding box to create a background spanning the whole tikzpicture:

1
2
3
4
\begin{pgfonlayer}{bg2} 
    \filldraw [line width=4mm,join=round,color=blue!20]
    (current bounding box.south west) rectangle (current bounding box.north east);
\end{pgfonlayer}


References