4

I'd like to draw the Chomsky hierarchy using tikz, similar to:

Chomsky hierarchy

I have the following so far, for a subset of the hierarchy:

\documentclass[11pt]{article}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows,calc}
% ----------

\begin{document}
    \begin{tikzpicture}
        \tikzstyle{venn} = [ellipse, minimum height=3em, minimum width=12em, draw]
        \node [venn] (cs) at (0, $re.south$) {Context Sensitive};
        \node [venn, minimum height=10em] (re) at (0,0)  {Recursively Enumerable};
    \end{tikzpicture}
\end{document}

How can I:

  1. Anchor all of the shapes to the same point in the centre at the bottom of the diagram?

  2. Align the text to the top of each ellipse - is shift appropriate here?

2 Answers 2

4

Naively one may think this should be simple with fit but unfortunately ellipse fits are not tight by default. (See here for a tighter fit, but my naive attempt to use it did not yield the desired results.) So one may do it differently. Note that this is not absolutely fool-proof but can be made so with more efforts. However, for the case at hand it works.

\documentclass[11pt]{article}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric,calc}
\begin{document}
    \begin{tikzpicture}[font=\sffamily,breathe dist/.initial=2ex]
    \foreach \X [count=\Y,remember=\Y as \LastY] in 
    {regular,context free,context sensitive,recursively enumerable}
     {\ifnum\Y=1
      \node[ellipse,draw,outer sep=0pt] (F-\Y) {\X};
     \else
      \node[anchor=south] (T-\Y) at (F-\LastY.north) {\X};
      \path let \p1=($([yshift=\pgfkeysvalueof{/tikz/breathe dist}]T-\Y.north)-(F-\LastY.south)$),
      \p2=($(F-1.east)-(F-1.west)$),\p3=($(F-1.north)-(F-1.south)$)
      in ($([yshift=\pgfkeysvalueof{/tikz/breathe dist}]T-\Y.north)!0.5!(F-\LastY.south)$) 
      node[minimum height=\y1,minimum width={\y1*\x2/\y3},
      draw,ellipse,inner sep=0pt] (F-\Y){};
     \fi}
    \end{tikzpicture}
\end{document}

enter image description here

And a version for Minhthien_2016:

\documentclass[11pt]{article}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric,calc,decorations.text}
\begin{document}
    \begin{tikzpicture}[font=\sffamily,breathe dist/.initial=4ex]
    \foreach \X [count=\Y,remember=\Y as \LastY] in 
    {regular,context free,context sensitive,recursively enumerable}
     {\ifnum\Y=1
      \node[ellipse,draw,outer sep=0pt] (F-\Y) {\X};
     \else 
      \path[decoration={text along path,
        text={|\sffamily|\X},text align=center,raise=0.3ex},decorate] 
        let \p1=($(F-\LastY.north)-(F-\LastY.west)$)
       in (F-\LastY.west) arc(180:0:\x1 and \y1);
      \path let \p1=($([yshift=\pgfkeysvalueof{/tikz/breathe dist}]F-\LastY.north)
      -(F-\LastY.south)$),
      \p2=($(F-1.east)-(F-1.west)$),\p3=($(F-1.north)-(F-1.south)$)
      in ($([yshift=\pgfkeysvalueof{/tikz/breathe dist}]F-\LastY.north)!0.5!(F-\LastY.south)$) 
      node[minimum height=\y1,minimum width={\y1*\x2/\y3},
      draw,ellipse,inner sep=0pt] (F-\Y){};
     \fi}
    \end{tikzpicture}
\end{document}

enter image description here

12
  • Can I format texs are also ellipses? Apr 13, 2019 at 7:26
  • @minhthien_2016 Sorry, I do not understand this question.
    – user121799
    Apr 13, 2019 at 13:34
  • It looks like word art in Word. Apr 13, 2019 at 14:08
  • I like the flexibility of this solution, and there's a bit more room for the text to breathe - thanks! Apr 13, 2019 at 16:53
  • 1
    @EkanshdeepGupta The relevant command is \path[decoration={text along path, text={<text>},text align=center,raise=0.3ex},decorate] <path>; These things are described in detail in section 50.6 Text Decorations of pgfmanual v1.3.1.
    – user121799
    Jul 11, 2019 at 13:10
5

This is not a perfect solution, but it fits this particular case: write words above another node.

\documentclass[tikz]{standalone}
\usetikzlibrary{shapes}
\begin{document}
\begin{tikzpicture}
\node[above,ellipse,minimum height=2em,minimum width=4em,draw] (a) {regular};
\node[above,ellipse,minimum height=4em,minimum width=8em,draw] (b) {};
\node[above,ellipse,minimum height=6em,minimum width=12em,draw] (c) {};
\node[above,ellipse,minimum height=8em,minimum width=16em,draw] (d) {};
\path (a.north) node[above] {context-free}
    (b.north) node[above] {context-sensitive}
    (c.north) node[above] {recursively enumerable};
\end{tikzpicture}
\end{document}

enter image description here

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.