Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am trying to draw this picture.

enter image description here

I have produced multiple balloons etc., but it would be nice to produce exactly same figure. In case my primitive code may help someone, I am also adding it below:

\documentclass[12pt]{article}
\usepackage{tikz}
\usetikzlibrary{calc,shapes.callouts,shapes.arrows}

\newcommand{\bubblethis}[2]{
\tikz[remember picture,baseline]{\node[anchor=base,inner sep=0,outer sep=0]%
(#1) {#1};\node[overlay,cloud callout,callout relative pointer={(-0.1cm,-0.1cm)},%
aspect=10,fill=yellow!90] at ($(#1.north)+(0.8cm,1.5cm)$) {#2};}%
}%

\newcommand{\bubblethat}[2]{
\tikz[remember picture,baseline]{\node[anchor=base,inner sep=0,outer sep=0]%
(#1) {#1};\node[overlay,cloud callout,callout relative pointer={(0cm,-0.5cm)},%
aspect=10,fill=yellow!90] at ($(#1.north)+(0.1cm,2.2cm)$) {#2};}%
}%

 \newcommand{\bubble}[3]{
 \tikz[remember picture,baseline]{\node[anchor=base,inner sep=0,outer sep=0] %
(#1)  {#1};\node[overlay,cloud callout,callout relative pointer={(0cm,-0.5cm)},aspect=8,fill=red] at($(#1.north)+(0.1cm,2.2cm)$) {#2};\node[overlay,cloud callout, callout relative pointer={((-0.4,-0.3))},aspect=2.5,fill=green] at($(#1.north)+(2cm,5cm)$) {#3};}
} %

\newcommand{\bubblesmall}[3]{
\tikz[remember picture,baseline]{\node[anchor=base,inner sep=0,outer sep=0] %
(#1)  {#1};\node[overlay,cloud callout,callout relative pointer={(0cm,-0.5cm)},aspect=8,fill=red] at($(#1.north)+(0.1cm,2.2cm)$) {#2};\node[overlay,cloud callout, callout relative pointer={((-0.4,-0.3))},aspect=2.5,fill=green] at($(#1.north)+(2cm,4cm)$) {#3};}
} %

Thanks for any help!

share|improve this question
    
A related question by the same user: tex.stackexchange.com/questions/183348/talking-balloon-in-tikz –  Steven B. Segletes Aug 28 at 17:31

1 Answer 1

up vote 41 down vote accepted
+100

Possibly one of those occasions where nesting the tikzpicture environment (which is usually inadvisable) can be quite useful.

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{shapes.callouts,decorations.pathmorphing}
\begin{document}

\tikzset{people/.cd,
  name/.store in=\personname,
  name=,
%
% Face
%
  face size/.store in=\facesize,
  face size=1cm,
    face/.style={fill=face color, draw=none},
  face color/.code=\colorlet{face color}{#1}, face color=black!50,
  face code/.initial={
    \path [people/face/.try]
    ( 0, 6) .. controls ( 3, 6) and ( 5, 4) .. 
    ( 5, 2) .. controls ( 7, 3) and ( 6,-2) ..
    ( 5,-1) .. controls ( 5,-4) and ( 2,-7) ..
    ( 0,-7) .. controls (-2,-7) and (-5,-4) .. 
    (-5,-1) .. controls (-6,-2) and (-7, 3) ..
    (-5, 2) .. controls (-5, 4) and (-3, 6) ..
    ( 0, 6) -- cycle;
  },
/tikz/people/.cd,
  hair/.style={fill=hair color, draw=none},
  hair back code/.initial=,
  hair front code/.initial=,
  hair color/.code=\colorlet{hair color}{#1}, hair color=black,
  hair style/.is choice,
  hair style/.cd,
    shoulder length/.style={
      hair back code={
        \path [people/hair/.try]
        ( 5,-1) ellipse [x radius=2, y radius=7]
        (-5,-1) ellipse [x radius=2, y radius=7];
      },
      hair front code={
        \path [people/hair/.try] 
        (3,4) ellipse [x radius=3, y radius=2] 
        (2,4) ellipse [x radius=4, y radius=2];
        \path [people/hair/.try] 
        ( 3,4) ellipse [x radius=3, y radius=2] 
        (-4,4) ellipse [x radius=2, y radius=2];
        \path [people/hair/.try]
        (6,4) arc (0:180:6 and 4) -- cycle;
      }
    },
    ceasar/.style={
      hair back code={
        \path [people/hair/.try]
        (-4,3) ellipse [x radius=2, y radius=3]
        ( 4,3) ellipse [x radius=2, y radius=3];
      },
      hair front code={
        \path [people/hair/.try]
        (5,4) arc (0:180:5 and 3);
        \path [people/hair/.try]
        ( 0,3) -- (-1,4) -- (-2,3) -- (-3,4) -- (-4,2) -- (-5,4) -- (-4,5) --
        ( 4,5) -- ( 5,4) -- ( 4,2) -- ( 3,4) -- ( 2,3) -- ( 1,4) -- cycle;
      }
    },
}

\tikzset{%
  pics/person/.style={%
    code={
      \tikzset{people/.cd,#1, /tikz/.cd,scale=\facesize/13cm}%
      \begin{scope}[local bounding box/.expanded=\personname]
      \pgfkeysvalueof{/tikz/people/hair back code}
      \pgfkeysvalueof{/tikz/people/face code}
      \pgfkeysvalueof{/tikz/people/hair front code}
      \pgfkeysvalueof{/tikz/people/facial hair code}
      \end{scope}
    } 
  },
  think bubble/.style={
    align=center,
    ellipse callout,
    minimum width=1cm,
    minimum height=0.75cm, 
    anchor=pointer,
    decoration={random steps, segment length=5pt, amplitude=1pt}, decorate
  }
}
\begin{tikzpicture}

\pic {person={hair style/ceasar, name=jack}};
\node [think bubble, fill=gray!50] at (jack.north) {$z$};


\pic at (2.5,0) {person={hair style/shoulder length, name=jill}};
\node [think bubble, fill=gray!25] at (jill.north) {%
\begin{tikzpicture}[scale=0.75, transform shape]
   \pic {person={hair style/ceasar, name=jack}};
   \node [think bubble, fill=gray!50] at (jack.north) {$z$};
\end{tikzpicture}\\$y$};


\pic at (6,0) {person={hair style/ceasar, name=jack}};
\node [think bubble, fill=gray!50] at (jack.north) {%
\begin{tikzpicture}[scale=0.75, transform shape]
  \pic {person={hair style/shoulder length, name=jill}};
  \node [think bubble, fill=gray!25]at (jill.north) {%
  \begin{tikzpicture}[scale=0.5, transform shape]
     \pic {person={hair style/ceasar, name=jack}};
     \node [think bubble, fill=gray!50] at (jack.north) {$z$};
  \end{tikzpicture}\\$y$};
\end{tikzpicture}\\$x$};

\end{tikzpicture}
\end{document}

enter image description here

And if more hairstyles are required then one can simply take from these:

\documentclass[tikz,border=5]{standalone}

\begin{document}

\tikzset{%
  face size/.store in=\facesize, 
  face size=1cm,
    face/.style={fill=face color, draw=none},
  face color/.code=\colorlet{face color}{#1}, face color=black!50,
  face code/.initial={
    \path [face/.try]
    ( 0, 6) .. controls ( 3, 6) and ( 5, 4) .. 
    ( 5, 2) .. controls ( 7, 3) and ( 6,-2) ..
    ( 5,-1) .. controls ( 5,-4) and ( 2,-7) ..
    ( 0,-7) .. controls (-2,-7) and (-5,-4) .. 
    (-5,-1) .. controls (-6,-2) and (-7, 3) ..
    (-5, 2) .. controls (-5, 4) and (-3, 6) ..
    ( 0, 6) -- cycle;
  }
}

\tikzset{ 
    facial hair/.style={fill=hair color, draw=none},
    facial hair code/.initial=,
  facial hair/.cd,
    clean shaven/.style={
        facial hair code=,
    },
    moustache/.style={
        facial hair code={
            \path [facial hair/.try]
            (0,-1) 
            .. controls ( 1, 0) and ( 2,-2) .. ( 2,-3)
            .. controls ( 1,-3) and ( 1,-2) .. ( 0,-2)
            .. controls (-1,-2) and (-1,-3) .. (-2,-3)
            .. controls (-2,-2) and (-1, 0) .. (0, -1)
            -- cycle;
        }
    },
    goatee/.style={
        facial hair code={
            \path [facial hair/.try]
            (0,-5) circle [radius=3];
            \path [face/.try]
            (0,-4) ellipse [x radius=2, y radius=1];
        }
    },
    beard/.style={
        facial hair code={
                \path [facial hair/.try]
                [shift=({-3,-4.5}), rotate=30]  ellipse [x radius=1.5, y radius=3.5];
                \path [facial hair/.try]
                [shift=({ 3,-4.5}), rotate=-30] ellipse [x radius=1.5, y radius=3.5];
                \path [facial hair/.try]
                (0,-5) ellipse [x radius=4, y radius=3];
                \path [face/.try]
                (0,-4) ellipse [x radius=2, y radius=1];
            }
    },
    stubble/.style={
        facial hair code={
            \path [facial hair/.try, fill=hair color!50!face color]
            ( 0,-2) 
            .. controls ( 2,-2) and ( 3,-4) .. ( 5,-1) 
            .. controls ( 5,-4) and ( 2,-7) .. ( 0,-7)
            .. controls (-2,-7) and (-5,-4) .. (-5,-1)
            .. controls (-3,-4) and (-2,-2) .. ( 0,-2)
            -- cycle;
            \path [face/.try]
            (0,-4) ellipse [x radius=2, y radius=1];
        }
    }
}
\tikzset{
  hair/.style={fill=hair color, draw=none},
  hair back code/.initial=,
  hair front code/.initial=,
  hair color/.code=\colorlet{hair color}{#1}, hair color=black,
  hair style/.is choice,
  hair style/.cd,
    none/.style={
      hair back code=,
      hair front code=,
    },
    bald/.style={
      hair back code={
        \path [hair/.try]
        (4, 2) ellipse [x radius=2, y radius=3]
        (-4,2) ellipse [x radius=2, y radius=3];
      },
      hair front code=,
    },
    curly/.style={
      hair back code={
        \path [hair/.try]
        (5, -5) circle [radius=2] (-5,-5) circle [radius=2]
        (6, -2) circle [radius=2] (-6,-2) circle [radius=2]
        (-6, 1) circle [radius=2] (6, 1)  circle [radius=2];
      },
      hair front code={
        \path [hair/.try] 
        (5,4) circle [radius=2] 
        (3,6) circle [radius=2]
        (-5,4) circle [radius=2] 
        (-3,6) circle [radius=2]
        (0,6) circle [radius=2];
      }
    },
    punk/.style={
      hair back code={
        \path [hair/.try]
        (-1, 5) -- ( 0, 8) -- ( 1, 5) -- cycle
        (-4, 3) -- (-6, 6) -- (-3, 4) -- cycle
        ( 4, 3) -- ( 6, 6) -- ( 3, 4) -- cycle
        (-3, 5) -- (-3, 7) -- (-1, 5) -- cycle
        ( 3, 5) -- ( 3, 7) -- ( 1, 5) -- cycle;
      },
      hair front code={
        \path [hair/.try] 
        (-3, 3) -- (-4, 5) -- (-2, 4) -- cycle
        ( 3, 3) -- ( 4, 5) -- ( 2, 4) -- cycle
        (-1, 4) -- ( 0, 6) -- ( 1, 4) -- cycle
        (-1, 2) -- ( 0, 3) -- ( 1, 2) -- cycle;
      }
    },
    bob/.style={
      hair back code={
        \path [hair/.try]
        ( 5,0) ellipse [x radius=2, y radius=6]
        (-5,0) ellipse [x radius=2, y radius=6];
        \path [hair/.try]
        (-5,-6) rectangle (5, -2);
      },
      hair front code={
        \path [hair/.try] 
        ( 3,4) ellipse [x radius=3, y radius=2] 
        (-3,4) ellipse [x radius=3, y radius=2];
        \path [hair/.try]
        (6, 4) arc (0:180:6 and 4) -- cycle;
      }
    },
    shoulder length/.style={
      hair back code={
        \path [hair/.try]
        ( 5,-1) ellipse [x radius=2, y radius=7]
        (-5,-1) ellipse [x radius=2, y radius=7];
      },
      hair front code={
        \path [hair/.try] 
        (3,4) ellipse [x radius=3, y radius=2] 
        (2,4) ellipse [x radius=4, y radius=2];
        \path [hair/.try] 
        ( 3,4) ellipse [x radius=3, y radius=2] 
        (-4,4) ellipse [x radius=2, y radius=2];
        \path [hair/.try]
        (6,4) arc (0:180:6 and 4) -- cycle;
      }
    },
    neutral/.style={
      hair back code={
        \path [hair/.try]
        ( 4,1) ellipse [x radius=2, y radius=4]
        (-4,1) ellipse [x radius=2, y radius=4];
      },
      hair front code={
        \path [hair/.try]
        (-5,2) ellipse [x radius=1, y radius=2]
        ( 5,2) ellipse [x radius=1, y radius=2];
        \path [hair/.try]
        (-6,2) 
        .. controls (-6,5) and (-3,7) .. ( 0,7) 
        .. controls ( 3,7) and ( 6,5) .. ( 6,2)
        .. controls ( 4,2) and ( 3,2) .. ( 2,4)
        .. controls ( 1,2) and (-3,0) .. (-6,2) -- cycle;
      }
    },
    afro 70s/.style={
      hair back code={
        \path [hair/.try]
        (0,2) ellipse [x radius=7, y radius=6];
      },
      hair front code={
        \path [hair/.try]
        ( 0,7)
        .. controls ( 3,7) and ( 6,2) .. ( 5,3)
        .. controls ( 2,6) and (-3,1) .. (-5,4)
        .. controls (-6,6) and (-3,7) .. ( 0,7)
        -- cycle;
        \path [hair/.try]
        (-4, 5) 
        .. controls (-4, 3) and (-5, 0) .. (-4,-2)
        .. controls (-3,-4) and (-3,-5) .. (-4,-4)
        .. controls (-5,-3) and (-7, -1) .. (-6, 3)
        .. controls (-6, 5) and (-5, 5) .. (-4, 5)
        -- cycle;
        \path [hair/.try, xscale=-1]
        (-4, 5) 
        .. controls (-4, 3) and (-5, 0) .. (-4,-2)
        .. controls (-3,-4) and (-3,-5) .. (-4,-4)
        .. controls (-5,-3) and (-7, -1) .. (-6, 3)
        .. controls (-6, 5) and (-5, 5) .. (-4, 5)
        -- cycle;       
      }
    },
    scruffy/.style={
      hair back code={
        \path [hair/.try]
        (-6,1) -- (-7,2) -- (-6,3) -- (-7,4) -- (-6,5) -- (-6,6) -- 
        (-5,6) -- (-4,7) -- (-3,7) -- (-2,8) -- (-1,7) -- ( 0,8) --
        ( 1,7) -- ( 2,8) -- ( 3,7) -- ( 4,7) -- ( 5,6) -- ( 6,6) --
        ( 6,5) -- ( 7,4) -- ( 6,3) -- ( 7,2) -- ( 6,1) -- cycle; 
      },
      hair front code={
        \path [hair/.try]
        (0,2) -- (-1,3) -- (-2,2) -- (-3,2) -- (-4,1) -- (-5,2) -- (-5,4) --
        (-1,7) -- (1,7) --
        (5,4) -- (5,2) -- (4,1) -- (3,2) -- (2,2) -- (1,3) -- cycle;
      }
    },
    pig-tails/.style={
      hair back code={
        \path [hair/.try]
        (-4,1) ellipse [x radius=2, y radius=4]
        ( 4,1) ellipse [x radius=2, y radius=4];
      },
      hair front code={
        \path [hair/.try]
        ( 0,3) .. controls (-3,1) and (-4,2) ..
        (-5,1) .. controls (-6,5) and (-3,6) ..
        ( 0,6) .. controls ( 3,6) and ( 6,5) ..
        ( 5,1) .. controls ( 4,2) and ( 3,1) ..
        ( 0,3) -- cycle;
        \path [hair/.try]
        (-4,3) -- (-8,6) -- (-7,6) -- (-8,8) -- 
        (-6,7) -- (-6,8) -- (-3,4) -- cycle
        ( 4,3) -- ( 8,6) -- ( 7,6) -- ( 8,8) -- 
        ( 6,7) -- ( 6,8) -- ( 3,4) -- cycle;
      }
    },
    ceasar/.style={
      hair back code={
        \path [hair/.try]
        (-4,3) ellipse [x radius=2, y radius=3]
        ( 4,3) ellipse [x radius=2, y radius=3];
      },
      hair front code={
        \path [hair/.try]
        (5,4) arc (0:180:5 and 3);
        \path [hair/.try]
        ( 0,3) -- (-1,4) -- (-2,3) -- (-3,4) -- (-4,2) -- (-5,4) -- (-4,5) --
        ( 4,5) -- ( 5,4) -- ( 4,2) -- ( 3,4) -- ( 2,3) -- ( 1,4) -- cycle;
      }
    },
    male short/.style={
       hair back code={
        \path [hair/.try]
        (-4,3) ellipse [x radius=2, y radius=3]
        ( 4,3) ellipse [x radius=2, y radius=3];
      },
      hair front code={
        \path [hair/.try]
        ( 0,7) .. controls (-3,7) and (-5,6) .. 
        (-5,4) .. controls (-5,0) and ( 1,5) ..
        ( 5,4) .. controls ( 5,6) and ( 3,7) ..
        ( 0,7) -- cycle;
      }
    },
    side parting/.style={
      hair back code={
        \path [hair/.try]
        ( 4,1) ellipse [x radius=2, y radius=4]
        (-4,1) ellipse [x radius=2, y radius=4];
      },
      hair front code={
        \path [hair/.try,xscale=-1]
        (-6,2) 
        .. controls (-6,5) and (-3,7) .. ( 0,7) 
        .. controls ( 3,7) and ( 6,5) .. ( 6,2)
        .. controls ( 4,2) and ( 3,2) .. ( 2,4)
        .. controls ( 1,2) and (-3,0) .. (-6,2) -- cycle;
      }
    },
    afro/.style={
    hair back code={
            \path [hair/.try]
            (0,2) ellipse [x radius=7, y radius=6];
          },
        hair front code={
            \path [hair/.try]
            (0,7)
            .. controls ( 3,7) and ( 5,6) .. ( 5,4)
            .. controls ( 3,0) and (-3,5) .. (-5,3)
            .. controls (-5,5) and (-3,7) .. ( 0,7)
            -- cycle;
        },
    }
}

\tikzset{%
  pics/person/.style={%
    code={
      \tikzset{#1, scale=\facesize/13cm}%
      \pgfkeysvalueof{/tikz/hair back code}
      \pgfkeysvalueof{/tikz/face code}
      \pgfkeysvalueof{/tikz/hair front code}
      \pgfkeysvalueof{/tikz/hair front code}
      \pgfkeysvalueof{/tikz/facial hair code}
    } 
  }
}

\begin{tikzpicture}
\foreach \hairstyle [count=\i from 0] in {none,bald,curly,punk,bob,shoulder length,%
neutral,afro,scruffy,pig-tails,ceasar,male short,side parting,afro 70s}{
  \path ({mod(\i,4)*2}, {-floor(\i/4)*2}) 
    node [below=0.5cm, font=\small, text height=1em] {\hairstyle} 
    pic {person={hair style/\hairstyle}};
}

\foreach \facialhair [count=\i from 16]in {clean shaven,moustache,beard,goatee,stubble}{

  \path  ({mod(\i,4)*2}, {-floor(\i/4)*2})
     node [below=0.5cm, font=\small, text height=1em] {\facialhair} 
     pic {person={facial hair/\facialhair}};
}
\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer
11  
You are an artist. –  Manuel Aug 29 at 11:45
1  
Did you find the paths for the hairstyles using trial and error, or with a drawing program? –  Jake Aug 31 at 15:23
1  
3  
@cyanide-basedfood (or whatever name this changes to in the future) the facial hair examples are all with a "default" head. The clean shaven option would "cancel out" any of the other facial hair options but the none hair style would not. Besides in my experience facial hair is independent of the hair on the top of the head; perhaps your experience is different. –  Mark Wibrow Aug 31 at 17:40
1  
@Jake for most of these I used Inkscape with the "snap to grid" option (as I prefer integer coordinates). Some of the hair styles were either simple tweaks of existing hair styles or just very simple and could be done by trial and error. –  Mark Wibrow Aug 31 at 17:55

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.