11

I would like to "shade" the faces of a commutative cube drawn using tikz-cd.

\documentclass{article}

\usepackage{tikz}
\usepackage{tikz-cd}

\begin{document}
\begin{tikzcd}
&
P
\ar{dl}[swap, sloped, near start]{t}
\ar{rr}{t'}
\ar[]{dd}[near end]{t}
& & R''
\ar{dd}{}
\ar{dl}[swap, sloped, near start]{}
\\
R
\ar[crossing over]{rr}[near start]{}
\ar{dd}[swap]{}
& & S''
\\
&
R'
\ar[near start]{rr}{}
\ar[sloped, near end]{dl}{}
& & S
\ar{dl}
\\
S'
\ar{rr}
& & P'
\ar[crossing over, leftarrow, near start]{uu}{}
\end{tikzcd}
\end{document}

enter image description here

One subtlety is that the vertices of this "cube" are not visible. However, there is a notional location for each vertex and I would like the shading to extend to that notional location. Really I'm just after a way of visually highlighting a face of the cube.

The shading should be quite transparent so that any edges of the cube that lie behind are still visible, and the arrows that lie along the edges of the shaded face are still clear.

Roughly speaking, I would like the effect of Drawing polyhedra using TikZ with semi-transparent and shading effect, but staying as much as possible within tikz-cd. I have a bunch of existing diagrams that I would like to animate by highlighting various faces in this way.

Is this possible, or would I need to rewrite my diagrams to use Tikz directly?

14

Yes, it's possible:

enter image description here

The code:

\documentclass{article}
\usepackage{tikz-cd}

\definecolor{cof}{RGB}{219,144,71}
\definecolor{pur}{RGB}{186,146,162}
\definecolor{greeo}{RGB}{91,173,69}
\definecolor{greet}{RGB}{52,111,72}

\begin{document}

\begin{tikzcd}[execute at end picture={
\foreach \Valor/\Nombre in   
{%
  tikz@f@1-2-1/a,tikz@f@1-1-2/b,tikz@f@1-1-4/c,tikz@f@1-2-3/d,%
  tikz@f@1-4-1/e,tikz@f@1-3-2/f,tikz@f@1-3-4/g,tikz@f@1-4-3/h%
}
{
\coordinate (\Nombre) at (\Valor);
}
\fill[pur,opacity=0.3] 
  (a) -- (b) -- (c) -- (d) -- cycle;
\fill[cof,opacity=0.3] 
  (a) -- (d) -- (h) -- (e) -- cycle;
\fill[greeo,opacity=0.3] 
  (h) -- (d) -- (c) -- (g) -- cycle;
  }
]
&
P
\ar{dl}[swap, sloped, near start]{t}
\ar{rr}{t'}
\ar[]{dd}[near end]{t}
& & R''
\ar{dd}{}
\ar{dl}[swap, sloped, near start]{}
\\
R
\ar[crossing over]{rr}[near start]{}
\ar{dd}[swap]{}
& & S''
\\
&
R'
\ar[near start]{rr}{}
\ar[sloped, near end]{dl}{}
& & S
\ar{dl}
\\
S'
\ar{rr}
& & P'
\ar[crossing over, leftarrow, near start]{uu}{}
\end{tikzcd}

\end{document}

The idea is to place a coordinate at each of the nodes in the diagram and then use those coordinates to do the filling; this is done using the execute at end picture key.

The internal numbering schema

Each node in a tikz-cd diagram has an internal name of the form

tikz@f@<number>-<row>-<column>

where <number> is the number of the tikz-cd diagram, <row> and <column> are the row and column, respectively, of the node. For example, the node labeled R in the above diagram (assuming it is the first tikz-cd diagram) would be

tikz@f@1-2-1

Had it been the 13th diagram, the internal name for R would've been

tikz@f@13-2-1

For example, the following shows, for each node, both its internal name and its new user-defined name. This is helpful if you want some guide during the filling process:

\documentclass{article}
\usepackage{tikz-cd}

\definecolor{cof}{RGB}{219,144,71}
\definecolor{pur}{RGB}{186,146,162}
\definecolor{greeo}{RGB}{91,173,69}
\definecolor{greet}{RGB}{52,111,72}

\begin{document}

\begin{tikzcd}[execute at end picture={
\foreach \Valor/\Nombre/\Posi in   
{%
  tikz@f@1-2-1/a/left,tikz@f@1-1-2/b/left,tikz@f@1-1-4/c/right,tikz@f@1-2-3/d/right,%
  tikz@f@1-4-1/e/left,tikz@f@1-3-2/f/left,tikz@f@1-3-4/g/right,tikz@f@1-4-3/h/right%
}
{
\coordinate (\Nombre) at (\Valor);
\node[\Posi=10pt,align=center] at (\Nombre) {\Valor\\ new name:\Nombre};
}
}
]
&
P
\ar{dl}[swap, sloped, near start]{t}
\ar{rr}{t'}
\ar[]{dd}[near end]{t}
& & R''
\ar{dd}{}
\ar{dl}[swap, sloped, near start]{}
\\
R
\ar[crossing over]{rr}[near start]{}
\ar{dd}[swap]{}
& & S''
\\
&
R'
\ar[near start]{rr}{}
\ar[sloped, near end]{dl}{}
& & S
\ar{dl}
\\
S'
\ar{rr}
& & P'
\ar[crossing over, leftarrow, near start]{uu}{}
\end{tikzcd}

\end{document}

enter image description here

If you don't want to keep finding the currect number of your diagram, you can use the associated internal count(er) \tikz@fig@count, but then something like

tikz@f@1-2-1

transforms into

tikz@f@\the\tikz@fig@count-2-1

and the resulting code is rather cumbersome:

\makeatletter
\begin{tikzcd}[
execute at end picture={
\foreach \Valor/\Nombre in   
{%
  tikz@f@\the\tikz@fig@count-2-1/a,tikz@f@\the\tikz@fig@count-1-2/b,tikz@f@\the\tikz@fig@count-1-4/c,tikz@f@\the\tikz@fig@count-2-3/d,%
  tikz@f@\the\tikz@fig@count-4-1/e,tikz@f@\the\tikz@fig@count-3-2/f,tikz@f@\the\tikz@fig@count-3-4/g,tikz@f@\the\tikz@fig@count-4-3/h%
}
{
\coordinate (\Nombre) at (\Valor);
}
\fill[cyan,opacity=0.15] 
  (a) -- (b) -- (c) -- (d) -- cycle;
\fill[orange,opacity=0.2] 
  (e) -- (f) -- (g) -- (h) -- cycle;
\fill[green,opacity=0.12] 
  (e) -- (a) -- (d) -- (h) -- cycle;
}
]
&
P
\ar{dl}[swap, sloped, near start]{t}
\ar{rr}{t'}
\ar[]{dd}[near end]{t}
& & R''
\ar{dd}{}
\ar{dl}[swap, sloped, near start]{}
\\
R
\ar[crossing over]{rr}[near start]{}
\ar{dd}[swap]{}
& & S''
\\
&
R'
\ar[near start]{rr}{}
\ar[sloped, near end]{dl}{}
& & S
\ar{dl}
\\
S'
\ar{rr}
& & P'
\ar[crossing over, leftarrow, near start]{uu}{}
\end{tikzcd}
\makeatother

A better approach

Using the alias key (and the standard |[...]| syntax for passing keys to nodes in a matrix), you can place easy-to-remember names to the nodes so you don't have to fiddle with the internal names and can use those simpler names for the shading:

\documentclass{article}
\usepackage{tikz-cd}

\definecolor{cof}{RGB}{219,144,71}
\definecolor{pur}{RGB}{186,146,162}
\definecolor{greeo}{RGB}{91,173,69}
\definecolor{greet}{RGB}{52,111,72}

\begin{document}

\begin{tikzcd}[execute at end picture={
\foreach \Nombre in  {A,B,...,H}
  {\coordinate (\Nombre) at (\Nombre.center);}
\fill[pur,opacity=0.3] 
  (A) -- (B) -- (C) -- (D) -- cycle;
\fill[greeo,opacity=0.3] 
  (A) -- (D) -- (H) -- (E) -- cycle;
\fill[cof,opacity=0.3] 
  (H) -- (D) -- (C) -- (G) -- cycle;
}]
&
|[alias=B]|P
\ar{dl}[swap, sloped, near start]{t}
\ar{rr}{t'}
\ar[]{dd}[near end]{t}
& & |[alias=C]|R''
\ar{dd}{}
\ar{dl}[swap, sloped, near start]{}
\\
|[alias=A]|R
\ar[crossing over]{rr}[near start]{}
\ar{dd}[swap]{}
& & |[alias=D]|S''
\\
&
|[alias=F]|R'
\ar[near start]{rr}{}
\ar[sloped, near end]{dl}{}
& & |[alias=G]|S
\ar{dl}
\\
|[alias=E]|S'
\ar{rr}
& & |[alias=H]|P'
\ar[crossing over, leftarrow, near start]{uu}{}
\end{tikzcd}

\end{document}

enter image description here

Use of backgrounds

For diagrams in which crossing over or description are not used, one can refine the answer doing the filling in a background layer; in this way, even with opacity=1 the filling doesn't affect labels nor arrows:

\documentclass{article}
\usepackage{tikz-cd}

\pgfdeclarelayer{background}
\pgfsetlayers{background,main}

\definecolor{cof}{RGB}{219,144,71}
\definecolor{pur}{RGB}{186,146,162}
\definecolor{greeo}{RGB}{91,173,69}
\definecolor{greet}{RGB}{52,111,72}

\begin{document}

\begin{tikzcd}[
execute at end picture={
  \begin{pgfonlayer}{background}
  \foreach \Nombre in  {A,B,...,E}
    {\coordinate (\Nombre) at (\Nombre.center);}
  \fill[pur!40] 
    (A) -- (B) -- (D) -- (C) -- cycle;
    \end{pgfonlayer}
}
]
  |[alias=A]|A
  \ar[rr,"f"]\ar[dd,"k"]\ar[dr,"\alpha"]
& & 
  |[alias=B]|B\ar[dd,"l",swap] 
\\
&
  |[alias=E]|E\ar[ur,"\beta"]\ar[dr,"\delta"] 
& 
\\
  |[alias=C]|C\ar[rr,"g"]\ar[ur,"\gamma"] 
& & 
  |[alias=D]|D 
\\
\end{tikzcd}

\end{document}

The result:

enter image description here

  • 3
    Amazing! Since I can not favorite the answer I favorited the question. What is the meaning of 1-2-1? I guess that entry (2,1) but what about the first 1? – Sigur Jul 24 '15 at 19:52
  • Yes, this exactly what I had in mind! Great. Is there a way to determine what coordinates to use for 1-2-1, etc? I'm starting with trial-and-error, but that's proving rather difficult... – Roly Jul 24 '15 at 20:16
  • @Roly It's easy. I am on the mobile now, but as soon as I have a computer in front, I'll add a remark. You can even use the alias key to make the naming easier. I'll also add this option. – Gonzalo Medina Jul 24 '15 at 20:30
  • Thanks Gonzalo, that would be very useful. My experiments so far are producing strange results (the vertices of the coloured regions don't seem to line up with the vertices of the cube), so maybe things will become clearer once I know what I'm doing with the coordinates. – Roly Jul 24 '15 at 20:32
  • 1
    @Sigur Thanks! I added an explanation about the meaning of the internal names (as you correctly guessed, the last two numbers in <number>-<row>-<column> give the row and column of the node; the first <number> refers to the number of the tikz-cd environment.) – Gonzalo Medina Jul 24 '15 at 22:10

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.