Tikz Templates

A collection of simple figures

Load TikZ in either one way.

  • \documentclass[tikz, border=2pt]{standalone}
  • \usepackage{tikz}


With pgfplots

PGF Plots automizes the axes configurations, for example:

  • major and minor ticks and labels on the axes
  • major and minor grid lines
  • legend styles and positioning

Explanation for the code:

  • \usepackage{pgfplots}: load package
  • \pgfplotsset{compat=1.18}: set dependency
  • \pgfplotsset{grid style={gray}}: draw grid lines
  • \pgfplotsset{major grid style={gray,line width=1}}: thicker major grid lines
  • axis equal: x and y-distances are in 1:1 ratio
  • axis lines=center: axes passes through the origin
  • grid=both: enable major grid lines
  • minor tick num=9: draw 9 minor grid lines between each pair of major grid lines
  • xlabel={$x$}, ylabel={$y$}: labels for the axes
  • title={}: title of a graph
  • legend style={at={(0,-0.05)},anchor=north west,fill=none}: legend styles
    • at={(0,-0.05)} coordinates relative to the entire PGF plot. (0,0) and (1,1) represent the bottom left and top right corners respectively.
    • anchor=north west: relative to the top left corner of the entire legend box
    • fill=none: (for TeXit) transparent background. TeXit renders a black background by default.
  • \begin{scope}[thick, samples=201, smooth]: avoid repetition of code
  • blue!20 is a shorthand for blue!20!white, meaning 20% blue and 80% white.
    grid style={gray},
    major grid style={gray,line width=0.7}
    axis equal,
    axis lines=center,
    minor tick num=9,
    title={Another \LaTeX{} graph},
    legend style={at={(0,-0.05)},anchor=north west,fill=none}
    \begin{scope}[thick, samples=201, smooth]
    \addplot[domain=-2.3:2.3, yellow] (x,{0.5 * x^2 - 1.5 * x - 4});
    \addlegendentry{$y = 0.5x^2-1.5x-4$};
    \addplot[domain=0:360,variable=\t, blue!20] ({sqrt(5) * cos(t)}, {sqrt(5) * sin(t)});
sample pgfplots SVG

sample TikZ + PGF plots

SVG generated with dvisvgm from PDF

    grid style={gray,opacity=0.3},
    major grid style={gray,line width=1,opacity=0.3}
    axis equal,
    axis lines=center,
    minor tick num=9,
    title={Sample \LaTeX{} complex plot},
\draw[red!40,fill=red!40,fill opacity=0.3] (-5,0) circle [radius=4];
\node at (-6.8,2.2) [red!30,rotate=45]{\scriptsize $|z+5| \le 4$};
    \clip (current axis.south west) rectangle (current axis.north east);
    \draw[fill=yellow,fill opacity=0.3] (-15,-10) -- (5,10) -- (current axis.south east) -- cycle;
    \node at (current axis.south east) [anchor=south east, yellow]{\scriptsize $\mathrm{Re}(ze^{i \pi/4}) \ge -5/\sqrt{2}$};
sample TikZ complex plot

sample LaTeX complex plot

SVG generated with dvisvgm from PDF

Special technical features of the above graph:

  • axis equal: ensure that the circle isn’t shown as an ellipse.
  • disabledatascaling: ensure that the circle is shown.
  • grid lines: I found that opacity=0.3 with line width=1 suits gray.
  • graph limits: I first tried xmin=-9 and xmax=3, but without ymin=-5 and ymax=7, I only got the graph of about [-1.5,1.5] × [-1,2].
  • enlargelimits={abs=0.5}: to ensure that the tips of the axes don’t overlap the labels for xmax and ymax.
  • the default cs (coordinate system) is axis cs inside the axis environment. This allows a simple syntax for a TikZ circle with [radius=<r>].
  • node at (P) [rotate=<deg>]{text}: rotate node content by <deg> anticlockwise.
  • fill opacity=0.3: shade the region with a light color, so that the math expression of the region can be written inside the filling.
  • current axis: contains points related to the two ends of each axis.

Code sample for a sample data plot

\begin{axis} [
title={sample \LaTeX{} graph},
axis lines=middle,
xlabel near ticks,
ylabel near ticks,
xlabel={$t$ time (s)},
ylabel={$h$ distance (cm)},
minor tick num=9,
grid style={line width=.1pt, draw=black!50},
major grid style={line width=.5pt,draw=black!50},
legend style={at={(1.05,1)},anchor=north west,fill=none},
\addplot[mark=*,thick] coordinates {
\addlegendentry{line 1}
\addplot[mark=*,thick,blue!50] coordinates {
\addlegendentry{line 2}
sample TikZ data plot

simple PGF data plot

SVG generated with dvisvgm from PDF

The $\LaTeX$ in the graph’s title has to be replaced by \LaTeX{} to avoid the error message

You can't use `\spacefactor' in math mode.

A large part of the code is copied from TeX.SE exchange.

    grid style={gray},
    major grid style={gray,line width=1},
    trig format plots=rad,
    legend columns=2,
\begin{axis}[axis lines=center,grid=both,
    restrict y to domain=-1.5:1.5,
    minor tick num=9,
    scaled x ticks={real:\PI},
    xtick scale label code/.code={},
    xtick distance=\PI/2,
        \ifdim \tick pt = 1 pt
        \else\ifdim \tick pt = -1 pt
                \strut$\pgfmathprintnumber[int detect]{\pgfmathresult}\pi$
    xticklabel style={
        /pgf/number format/frac,
        /pgf/number format/frac whole=false,
    title={Sample \LaTeX{} trigonometric graph},
    legend style={at={(0,-0.05)},anchor=north west,fill=none},
\addplot+ {sin(x)};
\addplot+ {cos(x)};
\addlegendentry{$y = \cos(x)$};
\addplot+[dashed] {tan(x)};
\addlegendentry{$y = \tan(x)$};
\foreach \k in {0,0.5,...,2} {\addplot[dashed] coordinates{({\k * \PI},-1.5) ({\k * \PI},1.5)};}
  • \pgfmathsetmacro{\PI}{3.141592654}: without this, the calculated \tick would become a strange fraction rather than π/2 when xtick distance=\PI.
  • scaled x ticks={real: \PI}: tick number \tick is divided by \PI. Outside xticklabel, the x-coordinate can be used as usual.
  • xticklabel and xticklabel style: set number plotting to fractions. In case that the numbers are ±1, the \ifdim would isolate the case, and omit the ‘1’ in the result.
  • restrict y to domain=-1.5:1.5: avoid tangent curves from bumping up the frame.
sample PGF trigonometric plot

simple PGF trigonometric plot

SVG generated with dvisvgm from PDF

Without pgfplot

An example copied from Discord.

    \draw[very thin, gray!30, step=1 cm](-4.9,-3.9) grid (4.9,3.9);

    \fill [gray, domain=-2:2, variable=\x]
    (-2, 0)
    -- plot ({\x}, {\x-1})
    -- (2, 0)
    -- cycle;

    \draw [thick] [->] (-5,0)--(5,0) node[right, below] {$x$};
    \foreach \x in {-4,...,4}
    \draw[xshift=\x cm, thick] (0pt,-1pt)--(0pt,1pt) node[below] {$\x$};

    \draw [thick] [->] (0,-4)--(0,4) node[above, left] {$y$};
    \foreach \y in {-3,...,3}
    \draw[yshift=\y cm, thick] (-1pt,0pt)--(1pt,0pt) node[left] {$\y$};

    \draw [domain=-2:2, variable=\x]
    plot ({\x}, {\x*\x}) node[right] at (1.5,2) {$f(x)=x^2$};

    \draw [domain=-2:3.5, variable=\x] plot ({\x}, {\x-1});
sample TikZ graph with grid without PGF plots

Example of TikZ plot without PGF plots

code copied from Discord



\draw[<->, >=latex, thick] (-3,0) -- (3,0) node [below, pos=0.5] {6 cm};
\draw[thick] circle (3);
\draw (0,0) node {$\bullet$};
sample TikZ circle

simple TikZ circle with given diameter

SVG generated with dvisvgm from PDF

  \draw (0,0) rectangle (3,7);
sample TikZ rectangle

sample TikZ rectangle with two given points

two endpoints of a diagonal

Right-angled triangle with the right angle mark.

\coordinate (O) at (0,0);
\coordinate (B) at (12,0);
\coordinate (H) at (0,16);
\draw[thick] (O) node [below left] {$O$}
-- (B) node [below, pos=0.5]{12} node [right] {$B$}
-- (H) node [above] {$H$}
-- cycle node [left, pos=0.5] {16};
\draw[thick] (0,1) -- (1,1) -- (1,0);

sample TikZ right-angled triangle with given side-lengths

Angle with mark.

\draw (x,y) arc (start:stop:radius); draws an arc.

\draw (0,0) node[below] {$O$};
\draw (2,0) node[right] {$A$};
\draw (2,2) node[right] {$B$};
\draw (0,0) -- (2,0);
\draw (0,0) -- (2,2);
\draw (1,0) arc (0:45:1);

sample TikZ angle

  • \newcommand\myvar{value} before \begin{document}
  • radius: radius length (i.e. distance of a vertex to the center), \r is used by the system.
  • n: number of sides
  • dTheta: size of angle of a sector
  • \the\numexpr\n-1: evalute n − 1.
    • I’m not sure if \n - 1 triggers an error because \n might be interpreted as text.
    • \numexpr\n-1 means \n-1 is a numerical expression.
    • \the preceeding \numexpr evaluates this expression.
  • \foreach \x in {1,...,m} {[cmd in terms of \x]}: use for loop to avoid repetition.

Improved stand alone example of regular polygon.

  every node/.style={draw,fill,circle,minimum size=6pt,inner sep=-2pt,},
  label distance=2.5mm,
  \foreach \k in {1,...,\n} {
    \node[label=\k*\dTheta:$V_\k$,label] (V\k) at ({\dTheta*\k}:\myR){};
  \draw (V1.center) foreach \k in {2,...,\n} { -- (V\k.center)} -- cycle;
  • every node/.style applies a series of styles inside [...] to every node.
    • node {$\bullet$} can’t represent the actual position described by the character ‘•’.
    • minimum size is the minimum diameter of the circular dot.
    • inner sep is the “signed space” between the perimeter of the content box and the node’s boundary (rendered by draw).
  • I’ve tried \draw (V1) -- foreach ... {} -- cycle but I got a logic error: the node edges were connected to the node boundary instead of the coordinate (V\k.center). This is known as TikZ’s “path shortening” effect, which is deactivated .
  • I’ve used an empty \node with a label=<angle>:<text> instead of a \coordinate with a pin=<angle>:<text> because
    1. \coordinate is a shorthand of \node[shape=coordinate], but I’m using a circular dot \node[draw,fill,shape=circle] to mark the actual position of the vertex. As a result, the actual shape=circle.
    2. I don’t want any pin edges. It would be more sensible to use labels instead of pins with every pin edge/.style={opacity=0}.
sample TikZ regular polygon

regular n-gon drawn with TikZ with n = 7

SVG generated with dvisvgm from PDF


    \draw[-latex] (0,0,0)--(1,0,0) node[pos=1.5]{$\vec{i}$};
    \draw[-latex] (0,0,0)--(0,1,0) node[pos=1.5]{$\vec{j}$};
    \draw[-latex] (0,0,0)--(0,0,1) node[pos=1.5]{$\vec{k}$};
    \foreach \k in {0,1} {\draw (0,0,\k)--(1,0,\k)--(1,1,\k)--(0,1,\k)--cycle;}
    \foreach \i in {0,1} \foreach \j in {0,1} \draw (\i,\j,0)--(\i,\j,1);
sample TikZ cube

sample cube with three axes

SVG generated with dvisvgm from PDF

Generate from Geogebra

99% of the guide/docs use Desktop version. Luckily, this Geogebra help thread provides a way to convert Geogebra figures to TikZ code on the web app.

const patNum = /[\d]+(\.([\d]+))?/g
const rplNum = a => Math.round((parseFloat(a)+Number.EPSILON)*100)/100
const patColor=/\\definecolor{(?<color>[a-z]+)}/g
const patLw=/line width=(\d+\.?\d*)pt/g
const rplLw = a => `lw${a.replace('.','p')}`
const axes = ['x', 'y']
const bddtypes = ['min', 'max']
const PGF_VERSION = 1.18
let myApp
let appNum = 0
new Function(`myApp = ${$('[id^="ggbApplet"]')[appNum].id}`)()
  const SCALE_FACTOR = rplNum(50/Math.max(...a.match(patNum).map(a=>parseFloat(a))))
  // build the array of colors
  while((match = patColor.exec(a)) !== null) {
    let color=match.groups.color;
    for (var i=1; i<=color.length; i++) {
      let colorShort=color.substring(0,i)
      if (myColors.find(c=>c.colorShort==colorShort)==null) {
  // round to 2dp, remove unnecessary styles, inject custom style holder
  output = a.replace(patNum,rplNum)
  // replace color=, fill= with short names
  myIdx = output.indexOf('\\tikzset{') + '\\tikzset{\n'.length
  myStyles = ''
  for (color of myColors) {
    for (word of ['color', 'fill']) {
        myStyles += `${word[0]}${color.colorShort}/.style={${word}=${color.color}},\n`
        let pat = new RegExp(`${word}=${color.color}`, 'g')
        output = output.replace(pat,`${word[0]}${color.colorShort}`)
  // build the set of line widths
  myLw=new Set()
  while((match = patLw.exec(output)) !== null) {
    line_width = match[1]
    if(!myLw.has(line_width)) {myLw.add(line_width)}
  // replace line width= with short names
  for (lw of myLw) {
    myStyles += `lw${lw.replace('.','p')}/.style={line width=${lw}pt},\n`
    let pat = new RegExp(`line width=${lw}pt`,'g')
    output = output.replace(pat,`lw${lw.replace('.','p')}`)
  // inject my styles into custom styles holder
  output = [output.slice(0,myIdx),myStyles,output.slice(myIdx)].join('')
  // remove extra spaces
  output = output.replace(/\\draw \[/g,'\\draw[')
  // restrict x,y domains to [xy](min|max)
  restrictStr = ''
  if (output.indexOf("\\begin{axis}") > -1){
    let xmin, xmax, ymin, ymax
    let bddstr, pat, bdd
    for (axis of axes) {
      for (bddtype of bddtypes) {
        bddstr = `${axis}${bddtype}`
        pat = new RegExp(`${bddstr}=(-?[\\d]+(\.([\\d]+))?)`)
        bdd = parseFloat(output.match(pat)[1])
        new Function(`${bddstr} = ${bdd}`)()
      new Function(`restrictStr += \`,\nrestrict ${axis} to domain=\$\{${axis}min\}:\$\{${axis}max\}\``)()
    let g0 = output.match(pat)[0]
    output = output.replace(pat,`${g0}${restrictStr}`)
  // print the output

I’m using my Geogebra activity about the Co-Side Theorem (共邊定理) as an example.

  1. (Optional step) Search “applet” in the page’s source code so as to find the applet’s ID.

    find Geogebra applet number with web dev tool

    In this example, the desired ID is 37303159.

  2. Type the first few letters of ggbApplet in the web developer tools’ console, followed by .

    enter ggbApplet with ID no. with tab

  3. Choose the function exportPGF() with the tab key.

    choose exportPGF() with tab

  4. Inside the bracket, type function(a){console.log(a}.

    press enter to get result

(Last modified on September 17, 2022)