342

The unique style of the diagrams at xkcd has an informative but nice hand-drawn touch. I guess they are actually drawn by hand but just recently on our partner site for Mathematica someone asked how to draw a similar diagram such as this one with Mathematica's plot functions (xkcd-style-graphs).

xkcd diagram

Now without Mathematica this should be possible as well but I have a hard time getting the details right. Can such a diagram be created in TeX with a similar design? My first attempt does not look particularly great but here it is (the font is from http://antiyawn.com/uploads/humorsans.html):

    \documentclass{standalone}
    \usepackage{tikz,color}
    \usepackage{pgfplots}
    \usepackage{fontspec}
    \setmainfont{Humor-Sans}

    \begin{document}
    \begin{tikzpicture}
    \pgfplotsset{every axis/.append style={line width=1pt}}

    \begin{axis}[%
        axis x line=bottom,
        axis y line=left,
        xtick={1.2, 2.9, 4.5},
        xticklabels={-3 days, -1 day, 5 minutes},
        yticklabels={}
    ]
    % 1st plot
    \addplot [cyan!80!white, samples=200, domain=0:6] {0.05*rnd+3+(sin(deg(x))^2)/sqrt(x)*exp(-(x-2))};
    % white background for 2nd plot
    \addplot [white, samples=200, domain=0:6,line width=4pt] {0.05*rnd+0.4*x+2+x^2*sin(deg(x))^2*exp(-x)}; 
    % 2nd plot
    \addplot [red!80!white, samples=200, domain=0:6] {0.05*rnd+0.4*x+2+x^2*sin(deg(x))^2*exp(-x)}; 
    \end{axis} 

    \node at (2.7,4.6) {downhill};
    \draw  plot[smooth, tension=.7,line width=2pt] coordinates {(1.2679,5.5206) (1.9454,5.493) (2.4017,4.9261)};

    \end{tikzpicture}

    \end{document}

first attempt

6
  • 1
    The reason why your plots seem to have too much noise in them is that you use the same number of samples for the random part. You could try creating a table with "clean" function values using pgfplotstable, then add random steps with a lower number of samples and plot the result.
    – Christoph
    Commented Oct 1, 2012 at 13:44
  • 3
    There is a variation of this using R to generate the graphic. With the intermediate use of knitr or sweave this can be integrated with LaTeX to import a very nice version of XKCD like graphics. See drunks-and-lampposts.com/2012/10/02/… I am going to use this technique to draw graphics for my statistics class to 'emulate' my handwriting. It will get a laugh. Commented Oct 3, 2012 at 0:12
  • 4
    Congratulations on the Great Question badge :)
    – cmhughes
    Commented Oct 3, 2012 at 15:23
  • 1
    I know I'm really late to the party, but xkcd is hand drawn. Source (check the title text).
    – Piccolo
    Commented Mar 30, 2013 at 22:35
  • 1
    This is also possible using matplotlib.
    – E.P.
    Commented Aug 29, 2014 at 9:51

4 Answers 4

327
+1000

This has been a topic for a few questions on this site and you can find many examples of such human-like typesetting, the most famous being the great

How do I make my document look like it was written by a Cthulhu-worshipping madman?

and also slightly related ones

Simulating hand-drawn lines

TikZ two-blocks matrix

that I can remember (because I've posted some answers) but please add more if I'm missing the obvious ones.

Regarding the answer, you can use decorations instead of random perturbations to your plots such that they are handled by TikZ instead. Also you can use a double line to achieve that white overlay over the previous line.

I don't have the Humor Sans font but I've used another similar font for using PDFLaTeX directly. Guys at SO have a better replacement for the font: xkcd style graphs in R

(The updated example needs XeLaTeX or LuaLaTeX!!)

\documentclass{standalone}
\usepackage{pgfplots}
\usepackage{fontspec}
\setmainfont{xkcd}

\begin{document}

\begin{tikzpicture}[decoration={random steps,segment length=1mm,amplitude=0.2pt}]
\pgfplotsset{every axis/.append style={line width=1pt}}

\begin{axis}[%
axis x line=middle,
axis y line=middle,
xtick={1.2, 2.9, 4.5},
xticklabels={-3 days, -1 day, 5 minutes},
yticklabels={},
every inner x axis line/.append style={-},
every inner y axis line/.append style={-},
decoration={random steps,segment length=5pt,amplitude=0.3pt},decorate,
every tick/.style={thick,black,decorate}
]
\begin{scope}[decoration={random steps,segment length=3pt,amplitude=0.5pt},decorate]
\addplot [cyan!80!white, samples=30, domain=0:6] {3+(sin(deg(x))^2)/sqrt(x)*exp(-(x-2))};
\addplot [white,double=red!80!white, samples=30, domain=0:6,double distance=1.0pt] {0.4*x+2+x^2*sin(deg(x))^2*exp(-x)}; 
\end{scope}
\end{axis}
\draw (1.2679,5.5206) to[bend left] (2.7,4.6) node[below] {downhill};
\begin{scope}[shift={(7cm,3cm)},thick]
\draw[line join=round,decorate] (0.6cm,-0.1cm) arc (45:275:0.4cm) arc (275:410:0.38cm);
\draw[decorate] (0.4cm,-0.9cm)coordinate (n) -- ++(0.1,-1cm) coordinate (a) -- +(-70:1.2cm) (a) --+(-110:1.2cm);
\draw[decorate] (n) -- ++(-5:0.4cm) --+(10:0.5cm);
\draw[decorate] (n) -- ++(-55:0.4cm) --+(2:0.5cm);
\node[align=left,scale=0.5] (c) at (0.5,2){I WON'T EVEN TRY \\TO BE FUNNY LIKE XKCD};
\draw[thin] (c) to[in=110,out=-90] ++(0,-0.5cm) node[below,align=left,scale=0.5] 
(d) {BUT THEN AGAIN, WHADDA\\ HELL! A NEUTRINO GOES \\TO A BAR...};
\draw[thin] (d) to[in=80,out=-90] ++(0,-1cm);
\end{scope}

\end{tikzpicture}

\end{document}

ba dum tss...

You can extend the effectiveness of the decoration to axes too if you remove the scope and supply the decoration options to the axis environment.

EDIT : added some clarification for the axes and some bonus stuff

EDIT2 : switched to a better font.


And finally I think it's not the wavy lines or the cartoonish display but the dry-humor of the author that makes them so funny so I don't think this would bring anything closer to those of xkcd.

14
  • 45
    Awesomeness has a name: percusse. :) Commented Oct 1, 2012 at 13:51
  • 131
    I've been holding the mouse over the plot for ages now and I have yet to see the punchline displayed. Commented Oct 1, 2012 at 14:07
  • 6
    the axes are still too straight IMO Commented Oct 1, 2012 at 14:10
  • 64
    I'm going to use this style in the thesis just to see my supervisor reaction... Commented Oct 1, 2012 at 16:34
  • 6
    @ClaudioFiandrino Added a student for you :)
    – percusse
    Commented Oct 1, 2012 at 16:42
118

If creating plots using matplotlib (python) is an option, take a look at "XKCDify " (sorry, this isn't a "TeX answer", but inclusion of matplotlib-generated plots in TeX documents is common enough I think it's worth mentioning this here).

enter image description here

26

I needed something like this and got inspired by the previous answer. I tried to clean up the code and to make it easy to use, as a single xkcd axis.

The single option changes the all style:

The sample plot with or without the option

Here is the code:

\documentclass{standalone}
\usepackage{pgfplots}
  \usepgflibrary{arrows.meta}

\usepackage{emerald}


\pgfplotsset{
  xkcd/.style={
    decoration={
      name=random steps,
      segment length=2pt,
      amplitude=0.3pt,
    },
    line width=1pt,
    line join=round,
    line cap=round,
    decorate,
  },
}
\pgfplotsset{
  xkcd axis/.style={%
    axis on top,
    xkcd,
    every non boxed x axis/.style={
      xtick align=center,
      enlarge x limits=true,
      x axis line style={-Straight Barb[round]}
    },
    every non boxed y axis/.style={
      ytick align=center,
      enlarge y limits=true,
      y axis line style={-Straight Barb[round]}
    },
    every tick/.append style={
      black,
      xkcd,
    },
    every axis plot post/.append style={
      double= . ,
      mark=none,
      draw=white,
      double distance=1pt,
    },
    every axis legend/.append style={
      xkcd,
    },
    tick label style={/pgf/number format/assume math mode=true},
    execute at begin axis={\ECFAugie},
  },
}


\begin{document}

\begin{tikzpicture}
  \begin{axis}[%
    xkcd axis,
    axis x line=bottom,
    axis y line=left,
    xtick={1.2, 2.9, 4.5},
    xticklabels={-3 days, -1 day, 5 minutes},
    xlabel=time,
    ylabel={what is this, exactly ?},
    ]
    \addplot +[samples=30, domain=1:6] {3+(sin(deg(x))^2)/sqrt(x)*exp(-(x-2))};
    \addlegendentry{Hello}
    \addplot +[samples=30, domain=1:6] {0.4*x+2+x^2*sin(deg(x))^2*exp(-x)}; 
    \addlegendentry{World}
  \end{axis}
\end{tikzpicture}
\begin{tikzpicture}
  \begin{axis}[%
    %xkcd axis,
    axis x line=bottom,
    axis y line=left,
    xtick={1.2, 2.9, 4.5},
    xticklabels={-3 days, -1 day, 5 minutes},
    xlabel=time,
    ]
    \addplot +[samples=30, domain=1:6] {3+(sin(deg(x))^2)/sqrt(x)*exp(-(x-2))};
    \addlegendentry{Hello}
    \addplot +[samples=30, domain=1:6] {0.4*x+2+x^2*sin(deg(x))^2*exp(-x)}; 
    \addlegendentry{World}
  \end{axis}
\end{tikzpicture}

\end{document}
1
  • Instead of \usepackage{emerald} you could install the font on your system and then \usepackage{fontspec} and \newfontfamily\ECFAugie{augie}. Works perfectly with XeLaTeX. Obviously you could name the new font family something more informative like \myxkcdfont.
    – PatrickT
    Commented Aug 27, 2022 at 14:11
21

A bit late, but I've just played around a bit and created an xkcd-like TikZ decoration. I probably added it to the wrong question. It's here. Example below.

Example adapted from matplotlib

You must log in to answer this question.

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