0

I am trying to produce this image, which includes three labels, and three graphs, all automatically generated by a (Java) program. The program generates graphs (specifically, of finite state automata) and employs LaTeX and TikZ to present these graphs to clients. The graphs tend to be large, often very large, and it is very difficult to pro-grammatically make adjustment to the process for the purpose of rendering.

enter image description here

The above image was generated by the LaTeX input at the end of this questions. You will notice that it is consists of three nodes, and three graphs. They are placed with magic numbers which I worked out manually. It is fairly easy to add anything before or after the graphs, but it is not possible to tweak the actual list of nodes and edges. It is also not possible to know in advance which nodes would be present on the graphs.

The question is whether it is possible to enclose the graphs and nodes with something that would compute their size, and place them, e.g., in a chain.

Yet another restriction is that the entire spiel should be in a single tikzpicture environment.

  \documentclass{sciposter}
  \usepackage[paperwidth=84cm,paperheight=120cm,centering,textwidth=74cm,textheight=100cm,left=2cm,top=2cm]{geometry}
  
  \usepackage{tikz}
  \begin{document}
  \usetikzlibrary{graphs,chains,shapes,quotes}
  \usetikzlibrary{automata, positioning, arrows}
  \usetikzlibrary{graphdrawing}
  \usegdlibrary{trees,force,layered,circular}
  \tikzstyle{accept}=[fill=green!50]
  \tikzstyle{initial}=[circle,draw]
  \tikzstyle{every node}=[rectangle]
  \tikzstyle{epsilon}=[]
  \tikzstyle{graphs/every graph}=[simple necklace layout,
  nodes={ellipse,fill=olive!20,inner sep=2pt,outer sep=2pt}, level sep =12ex, sibling sep=4ex, node distance = 35ex]
  
  
  \def\magicOne{(0,-3)}
  \def\magicTwo{(0,-63)}
  \def\magicThree{(0,-95)}
  \begin{tikzpicture}
  \node at (0,0) {\Huge NFSA};
  \node at (0,-61) {\Huge DFSA};
  \node at (0,-92)  {\Huge Minimized DFSA};
  \begin{scope} \path \magicOne
  graph{
     "$q_{0}$" [initial,accept] -> ["\varepsilon"] "$q_{1}$" ;
     "$q_{0}$"  -> ["a, b"] "$q_{2}$" ;
     "$q_{0}$"  -> [""] "$q_{3}$" ;
     "$q_{0}$"  -> [""] "$q_{8}$" ;
     "$q_{0}$"  -> ["\varepsilon",loop] "$q_{0}$" ;
     "$q_{1}$"  -> ["a, b"] "$q_{2}$" ;
     "$q_{1}$"  -> [""] "$q_{3}$" ;
     "$q_{1}$"  -> ["\varepsilon"] "$q_{8}$" ;
     "$q_{2}$"  -> ["a, b",loop] "$q_{2}$" ;
     "$q_{3}$"  -> ["b"] "$q_{2}$" ;
     "$q_{3}$"  -> ["a"] "$q_{4}$" ;
     "$q_{3}$"  -> [""] "$q_{5}$" ;
     "$q_{4}$"  -> ["a, b"] "$q_{2}$" ;
     "$q_{4}$"  -> ["\varepsilon"] "$q_{5}$" ;
     "$q_{5}$"  -> ["a"] "$q_{2}$" ;
     "$q_{5}$"  -> [""] "$q_{6}$" ;
     "$q_{5}$"  -> [""] "$q_{7}$" ;
     "$q_{5}$"  -> [""] "$q_{10}$" ;
     "$q_{5}$"  -> ["b"] "$q_{12}$" ;
     "$q_{6}$"  -> ["a, b"] "$q_{2}$" ;
     "$q_{6}$"  -> ["\varepsilon"] "$q_{7}$" ;
     "$q_{6}$"  -> ["\varepsilon"] "$q_{10}$" ;
     "$q_{7}$"  -> ["a"] "$q_{2}$" ;
     "$q_{7}$"  -> [""] "$q_{1}$" ;
     "$q_{7}$"  -> [""] "$q_{3}$" ;
     "$q_{7}$"  -> [""] "$q_{8}$" ;
     "$q_{7}$"  -> [""] "$q_{0}$" ;
     "$q_{7}$"  -> ["b"] "$q_{9}$" [accept];
     "$q_{8}$"  -> ["a, b"] "$q_{2}$" ;
     "$q_{8}$"  -> ["\varepsilon"] "$q_{3}$" ;
     "$q_{9}$"  -> [""] "$q_{1}$" ;
     "$q_{9}$"  -> ["a, b"] "$q_{2}$" ;
     "$q_{9}$"  -> [""] "$q_{3}$" ;
     "$q_{9}$"  -> [""] "$q_{8}$" ;
     "$q_{9}$"  -> ["\varepsilon"] "$q_{0}$" ;
     "$q_{10}$"  -> ["b"] "$q_{2}$" ;
     "$q_{10}$"  -> [""] "$q_{1}$" ;
     "$q_{10}$"  -> [""] "$q_{3}$" ;
     "$q_{10}$"  -> [""] "$q_{8}$" ;
     "$q_{10}$"  -> [""] "$q_{0}$" ;
     "$q_{10}$"  -> ["a"] "$q_{11}$" [accept];
     "$q_{11}$"  -> [""] "$q_{1}$" ;
     "$q_{11}$"  -> ["a, b"] "$q_{2}$" ;
     "$q_{11}$"  -> [""] "$q_{3}$" ;
     "$q_{11}$"  -> [""] "$q_{8}$" ;
     "$q_{11}$"  -> ["\varepsilon"] "$q_{0}$" ;
     "$q_{12}$"  -> ["\varepsilon"] "$q_{6}$" ;
     "$q_{12}$"  -> ["a, b"] "$q_{2}$" ;
     "$q_{12}$"  -> [""] "$q_{7}$" ;
     "$q_{12}$"  -> [""] "$q_{10}$" ;
  }
  ; \end{scope}
  
  \begin{scope} \path \magicTwo
  graph{
     "$q_{0}$" [initial,accept] -> ["b"] "$q_{1}$" ;
     "$q_{0}$"  -> ["a"] "$q_{2}$" ;
     "$q_{1}$"  -> ["a, b",loop] "$q_{1}$" ;
     "$q_{2}$"  -> ["a"] "$q_{1}$" ;
     "$q_{2}$"  -> ["b"] "$q_{3}$" ;
     "$q_{3}$"  -> ["a"] "$q_{4}$" [accept];
     "$q_{3}$"  -> ["b"] "$q_{5}$" [accept];
     "$q_{4}$"  -> ["b"] "$q_{1}$" ;
     "$q_{4}$"  -> ["a"] "$q_{2}$" ;
     "$q_{5}$"  -> ["b"] "$q_{1}$" ;
     "$q_{5}$"  -> ["a"] "$q_{2}$" ;
  }
  
  ; \end{scope}
  
  \begin{scope} \path \magicThree
  graph{
     "$q_{0}$" [initial,accept] -> ["b"] "$q_{1}$" ;
     "$q_{0}$"  -> ["a"] "$q_{2}$" ;
     "$q_{1}$"  -> ["a, b",loop] "$q_{1}$" ;
     "$q_{2}$"  -> ["a"] "$q_{1}$" ;
     "$q_{2}$"  -> ["b"] "$q_{3}$" ;
     "$q_{3}$"  -> ["a, b"] "$q_{0}$" ;
  }
  
  ; \end{scope}
  \end{tikzpicture}
  
  \end{document}
  
4
  • If you are interested in checking out the library for managing FSAs, you can find it here. github.com/yossigil/Automata
    – Yossi Gil
    Jul 9 at 17:49
  • "consists of three nodes, and three graphs" - I can count 13 nodes in the first graph!? "compute their size" - yes local bounding box does that, but why? "place them, e.g., in a chain" - you just want the three graph placed horizontal next to each other? that would be easy. Jul 14 at 8:31
  • @hpekristiansen, probably mean three styles of nodes, which differ only in fill color.
    – Zarko
    Jul 14 at 10:27
  • I thought \matrix is entirely for this purpose. If it's slow, use the pgf version.
    – Symbol 1
    Jul 14 at 17:14
2
+50

Here the graphs(from @Symbol 1) are in a chain:

\documentclass[tikz, border=1cm]{standalone}
\begin{document}
\begin{tikzpicture}[even odd rule]
\begin{scope}
\clip[shift={(13,-3)}] (-7.3,0) arc(180:270:5.2) -- (-1.5,-4.3) arc(270:180:4.3) -- cycle (-21,-6) rectangle (25,9);
\fill (6,5) arc( 90:-90:5) -- (-2,-5) arc( 270:90:5) -- cycle (-1.5,4.5) -- (5.5,4.5) arc( 90:-90:4.5) -- (-1.5,-4.5) arc( 270:90:4.5) -- cycle;
\draw foreach\i in{1,...,20}{
            foreach\j in{1,...,\j}{
                (\i*18:4)--(\j*18:4)
            }
        };
\end{scope}
\clip (6.2,5.2) arc(90:0:5.2) -- (9.6,0) arc(0:90:4.3) -- cycle (-8,-9) rectangle (38,6);        
\begin{scope}
\clip[shift={(26,0)}] (-7.3,0) arc(180:270:5.2) -- (-1.5,-4.3) arc(270:180:4.3) -- cycle (-22,-9) rectangle (12,6);
\fill[shift={(13,-3)}] (6,5) arc( 90:-90:5) -- (-2,-5) arc( 270:90:5) -- cycle (-1.5,4.5) -- (5.5,4.5) arc( 90:-90:4.5) -- (-1.5,-4.5) arc( 270:90:4.5) -- cycle;
\draw[shift={(15,-3)}] foreach\i in{1,...,10}{
            foreach\j in{1,...,\j}{
                (\i*36:2)--(\j*36:2)
            }
        };
\end{scope}
\clip[shift={(13,-3)}] (6.2,5.2) arc(90:0:5.2) -- (9.6,0) arc(0:90:4.3) -- cycle (0,-3) rectangle (25,9);
\fill[shift={(26,0)}] (6,5) arc( 90:-90:5) -- (-2,-5) arc( 270:90:5) -- cycle (-1.5,4.5) -- (5.5,4.5) arc( 90:-90:4.5) -- (-1.5,-4.5) arc( 270:90:4.5) -- cycle;
\draw[shift={(29,0)}] foreach\i in{1,...,15}{
            foreach\j in{1,...,\j}{
                (\i*24:3)--(\j*24:3)
            }
        };
\end{tikzpicture}
\end{document}

Graphs literally in a linked chain

3
  • 1
    That was fun. A lot.
    – SebGlav
    Jul 15 at 12:31
  • Amazing graphs!!
    – Yossi Gil
    Jul 18 at 14:02
  • How do I use these for automatically generated graphs?
    – Yossi Gil
    Jul 18 at 14:02
3

\matrix will compute the spacing/shifting for you

\documentclass{article}
\usepackage{fullpage,tikz}
\begin{document}
\tikz{
    \matrix{
        \draw foreach\i in{1,...,10}{
            foreach\j in{1,...,\j}{
                (\i*36:2)--(\j*36:2)
            }
        };
    \\
        \draw foreach\i in{1,...,15}{
            foreach\j in{1,...,\j}{
                (\i*24:3)--(\j*24:3)
            }
        };
    \\
        \draw foreach\i in{1,...,20}{
            foreach\j in{1,...,\j}{
                (\i*18:4)--(\j*18:4)
            }
        };
    \\}
}
\end{document}

1
  • 1
    foreach\j in{1,...,\j} is making so many senses. How come my code actually works???????
    – Symbol 1
    Jul 15 at 5:52

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.