11

I'm looking for some good examples of LaTeX code used to generate basic Cayley diagrams like this one:

D4 Group Diagram

Ideally, I'd like for the examples to make it fairly clear how to modify or remove various elements of the graph (labels, colors, line styles, etc.), and how to produce graphs for different basic groups.

1
  • On closer examination, I think this diagram (from Wikimedia Commons) is wrong, or at least requires a close reading of the text that accompanies the figure to parse. That's not material to the question here, and the answer is still valid, so I'll leave it as is, but I've provided a corrected diagram in my CW answer below.
    – orome
    May 19, 2012 at 4:31

3 Answers 3

13

TikZ should be pretty useful doing this. It's a package to 'draw' stuff in latex. I tried replicating your picture, there are still some rough edges, but it looks pretty nice I think.

\documentclass{article}
\usepackage{tikz}

\begin{document}
\usetikzlibrary{arrows,positioning}
\begin{tikzpicture} [%
    nd/.style = {circle,fill=black,text=white,inner sep=1pt},
    tn/.style = {node distance=1pt},
    redarrow/.style={->, red, fill=none,>=stealth},
    blueline/.style={-,blue,fill=none}]

    \node[nd] (otl) at (0,0) {\sffamily F};
    \node[nd] (itl) [below right=of otl] {\sffamily F};
    \node[nd] (itr) [right=of itl] {\sffamily F};
    \node[nd] (otr) [above right=of itr] {\sffamily F};
    \node[nd] (ibl) [below=of itl] {\sffamily F};
    \node[nd] (obl) [below left=of ibl] {\sffamily F};
    \node[nd] (ibr) [right=of ibl] {\sffamily F};
    \node[nd] (obr) [below right=of ibr] {\sffamily F};

    \draw[redarrow] (otr) -- (otl);
    \draw[redarrow] (otl) -- (obl);
    \draw[redarrow] (obl) -- (obr);
    \draw[redarrow] (obr) -- (otr); 
    \draw[redarrow] (itl) -- (itr);
    \draw[redarrow] (itr) -- (ibr);
    \draw[redarrow] (ibr) -- (ibl);
    \draw[redarrow] (ibl) -- (itl); 

    \draw[blueline] (ibl) -- (obl);
    \draw[blueline] (itl) -- (otl);
    \draw[blueline] (ibr) -- (obr);
    \draw[blueline] (itr) -- (otr);

    \node[tn] [below right=of itl] {\tiny{$a$}};
    \node[tn] [below left=of itr] {\tiny{$a^2$}};
    \node[tn] [above left=of ibr] {\tiny{$a^3$}};
    \node[tn] [above right=of ibl] {\tiny{$e$}};

    \node[tn] [below left=of obl] {\tiny{$b$}};
    \node[tn] [below=of obr] {\tiny{$ab=ba^3$}};
    \node[tn] [above=of otl] {\tiny{$ba=a^3b$}};
    \node[tn] [above=of otr] {\tiny{$a^2b=ba^2$}};

\end{tikzpicture}
\end{document}

which looks like

screenshot of the diagram

I would normally name the styles according to their uses, but since I have no idea what the diagram represents, I just named them according to their styles. The rotation is still missing, I'm trying to get that right though ;)

EDIT:

I got rotation etc. to work. Since the syntax is a little bit harder to read, I thought I would define a command for the nodes in the graph. I also fixed the text height for the 'captions', so that the ugly offset of the text is now gone. It's just the upper part that's changed, but in spirit of providing a MWE I also copied the rest of the code again:

\documentclass{article}
\usepackage{tikz}

\begin{document}
\usetikzlibrary{arrows,positioning}

\newcommand{\nd}[4]{\node[nd] (#1) #2 [label={[white,rotate=#3]center:{\sffamily #4}}] {}};

\begin{tikzpicture} [%
    nd/.style = {circle,fill=black,text=white,inner sep=4pt},
    tn/.style = {node distance=1pt,text height=0.5ex},
    redarrow/.style={->, red, fill=none,>=stealth},
    blueline/.style={-,blue,fill=none}]

    \nd{otl}{at (0,0)}{0}{F};
    \nd{itl}{[below right=of otl]}{270}{F};
    \nd{itr}{[right=of itl]}{0}{F};
    \nd{otr}{[above right=of itr]}{90}{x};
    \nd{ibl}{[below=of itl]}{90}{F};
    \nd{obl}{[below left=of ibl]}{0}{e};
    \nd{ibr}{[right=of ibl]}{180}{F};
    \nd{obr}{[below right=of ibr]}{90}{F};

    \draw[redarrow] (otr) -- (otl);
    \draw[redarrow] (otl) -- (obl);
    \draw[redarrow] (obl) -- (obr);
    \draw[redarrow] (obr) -- (otr); 
    \draw[redarrow] (itl) -- (itr);
    \draw[redarrow] (itr) -- (ibr);
    \draw[redarrow] (ibr) -- (ibl);
    \draw[redarrow] (ibl) -- (itl); 

    \draw[blueline] (ibl) -- (obl);
    \draw[blueline] (itl) -- (otl);
    \draw[blueline] (ibr) -- (obr);
    \draw[blueline] (itr) -- (otr);

    \node[tn] [below right=of itl] {\tiny{$a$}};
    \node[tn] [below left=of itr] {\tiny{$a^2$}};
    \node[tn] [above left=of ibr] {\tiny{$a^3$}};
    \node[tn] [above right=of ibl] {\tiny{$e$}};

    \node[tn] [below left=of obl] {\tiny{$b$}};
    \node[tn] [below=of obr] {\tiny{$ab=ba^3$}};
    \node[tn] [above=of otl] {\tiny{$ba=a^3b$}};
    \node[tn] [above=of otr] {\tiny{$a^2b=ba^2$}};

\end{tikzpicture}
\end{document}

better version of the diagram

3
  • That looks great. I'll play with that approach a bit too. Is there any advantage to using the petri library for this?
    – orome
    May 18, 2012 at 23:28
  • And: Don't worry too much about the rotation. In general it's hard to do (the 'F' works for this example, but different groups will need different objects and rotations). In fact, most diagrams will just have the labels, that are next to the nodes in the examples above, inside the nodes.
    – orome
    May 18, 2012 at 23:32
  • As I commented below, there is not much petri in your example, it's pretty much the same idea as mine. May 18, 2012 at 23:53
2

Experimenting (as a novice) with tikz and the petri library (whatever that is), I can use

\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{petri}
\tikzset{state/.style={circle,draw=gray,inner sep=0pt,minimum size=7mm,label=center:$#1$,name=#1},
redarrow/.style={->, red, fill=none,>=stealth},bluearrow/.style={->, blue, fill=none,>=stealth},  
redline/.style={-,red,fill=none},blueline/.style={-,blue,fill=none}}
\begin{tikzpicture}
\node[state=e]{};
\node[state=a,above=of e]{};
\node[state=a^2,right=of a]{};
\node[state=a^3,below=of a^2]{};
\node[state=b,below left=of e]{};
\node[state=ba^3,above left=of a]{};
\node[state=ba^2,above right=of a^2]{};
\node[state=ba,below right=of a^3]{};
\draw[redarrow](e)--(a);\draw[redarrow](b)--(ba);
\draw[redarrow](a)--(a^2);\draw[redarrow](ba)--(ba^2);
\draw[redarrow](a^2)--(a^3);\draw[redarrow](ba^2)--(ba^3);
\draw[redarrow](a^3)--(e);\draw[redarrow](ba^3)--(b);
\draw[blueline](e)--(b);
\draw[blueline](a)--(ba^3);
\draw[blueline](a^2)--(ba^2);
\draw[blueline](a^3)--(ba);
\end{tikzpicture}

to get this:

enter image description here

2
  • I'd like to also be able to define some styles (e.g. for edges and nodes) that allow me to make global changes to multiple diagrams easily, but I'm not sure how to do that.
    – orome
    May 18, 2012 at 23:25
  • 3
    You don't really need petri here. The only thing of petri you are using is [place], which you should be able to exchange against [circle,draw,inner sep=2pt] (I guessed the number). Then you pretty much arrive at my example May 18, 2012 at 23:45
1

Here's an attempt in plain Metapost, using two of the built-in transformation commands: rotated t and reflectedabout(p,q).

enter image description here

prologues := 3;
outputtemplate := "%j%c.eps";

beginfig(1);
% define the image of the F to transform
s = 16;
picture f;
f = image(fill fullcircle scaled s; label("F" infont "cmss10" scaled 1.2,origin) withcolor white;);

% define the 8 points we need
% it's convenient to have the origin at the centre.
z1 = 50 right rotated -135;
z2 = z1 rotated -90;
z3 = z2 rotated -90;
z4 = z3 rotated -90;
z5 = 2z1;
z6 = 2z2;
z7 = 2z3;
z8 = 2z4;

% loop to draw the lines, arrows, and the F suitably transformed
% the cutbefore/cutafter parts shorten the arrows to avoid the discs
for i=0 upto 3:
  draw z[i+1] -- z[5+i] withcolor blue;
  n := (i+1) mod 4 + 1;
  drawarrow z[i+1] -- z[n] 
            cutbefore fullcircle scaled s shifted z[i+1]
            cutafter  fullcircle scaled s shifted z[n]
            withcolor red;
  drawarrow z[n+4] -- z[i+5] 
            cutbefore fullcircle scaled s shifted z[n+4]
            cutafter  fullcircle scaled s shifted z[i+5]
            withcolor red;
  draw f                         rotated 90i shifted z[i+1];
  draw f reflectedabout(up,down) rotated 90i shifted z[i+5];
endfor

% add suitable labels, carefully positioned.
label(btex $e$   etex, .7 z1);
label(btex $a$   etex, .7 z2);
label(btex $a^2$ etex, .7 z3);
label(btex $a^3$ etex, .7 z4);

label.bot(btex $b$         etex, z5-(0,s/2));
label.top(btex $ba=a^3b$   etex, z6+(0,s/2));
label.top(btex $ba^2=a^2b$ etex, z7+(0,s/2));
label.bot(btex $ba^3=ab$   etex, z8-(0,s/2));

endfig;
end.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .