Skip to main content

LaTeX Timelines, Gantt Charts, and Chronological Visualizations

Published: March 7, 2026 Updated: May 8, 2026 Larry Qu 4 min read

Introduction

Timelines and Gantt charts are essential for visualizing sequences of events, project schedules, and historical chronologies. LaTeX provides several approaches: TikZ for custom timelines, pgfgantt for project Gantt charts, and the chronosys package for historical timelines.

Simple TikZ Timeline

A horizontal timeline with events:

\usepackage{tikz}
\usetikzlibrary{arrows.meta, positioning}

\begin{tikzpicture}[
  event/.style={circle, draw, fill=blue!20, minimum size=8pt, inner sep=0},
  label/.style={font=\small, text width=2.5cm, align=center}
]
  % Main timeline axis
  \draw[->, thick] (0,0) -- (12,0) node[right] {Time};

  % Year markers
  \foreach \x/\year in {0/2020, 3/2021, 6/2022, 9/2023, 12/2024} {
    \draw (\x, 0.1) -- (\x, -0.1);
    \node[below, font=\small] at (\x, -0.1) {\year};
  }

  % Events above the line
  \node[event] (e1) at (1, 0) {};
  \node[label, above=0.3cm of e1] {Project\\Launch};

  \node[event] (e2) at (4, 0) {};
  \node[label, above=0.3cm of e2] {Beta\\Release};

  \node[event] (e3) at (7, 0) {};
  \node[label, above=0.3cm of e3] {v1.0\\Release};

  \node[event] (e4) at (10, 0) {};
  \node[label, above=0.3cm of e4] {v2.0\\Release};

  % Events below the line
  \node[event, fill=red!20] (e5) at (2.5, 0) {};
  \node[label, below=0.3cm of e5] {Team\\Expansion};

  \node[event, fill=red!20] (e6) at (8, 0) {};
  \node[label, below=0.3cm of e6] {Series A\\Funding};
\end{tikzpicture}

Vertical Timeline

\begin{tikzpicture}[
  event/.style={rectangle, draw, fill=blue!10, rounded corners,
                minimum width=4cm, minimum height=0.8cm, text centered},
  year/.style={font=\bfseries\large, text=blue!70}
]
  % Vertical line
  \draw[thick, blue!50] (0, 0) -- (0, -12);

  % Events
  \foreach \y/\yr/\desc in {
    0/1969/{Unix created at Bell Labs},
    -2/1972/{C language developed},
    -4/1983/{GNU Project started},
    -6/1991/{Linux kernel released},
    -8/2000/{Mac OS X released},
    -10/2015/{Rust 1.0 released}
  } {
    \node[year] at (-1.5, \y) {\yr};
    \draw[thick] (-0.1, \y) -- (0.1, \y);
    \node[event] at (2.5, \y) {\desc};
    \draw[->] (0.1, \y) -- (0.5, \y);
  }
\end{tikzpicture}

Gantt Charts with pgfgantt

pgfgantt is the standard package for project Gantt charts:

\usepackage{pgfgantt}

\begin{ganttchart}[
  hgrid,
  vgrid,
  x unit=0.8cm,
  y unit title=0.6cm,
  y unit chart=0.5cm,
  title label font=\small,
  bar label font=\small,
  milestone label font=\small\itshape,
  bar/.append style={fill=blue!40},
  milestone/.append style={fill=red!60}
]{1}{16}

  % Title row
  \gantttitle{Project Schedule 2026}{16} \\
  \gantttitlelist{Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec}{1} \\
  % (simplified to 16 units for demo)

  % Tasks
  \ganttbar{Requirements}{1}{2} \\
  \ganttbar{Design}{2}{4} \\
  \ganttbar{Development}{4}{10} \\
  \ganttbar{Testing}{9}{12} \\
  \ganttbar{Deployment}{12}{13} \\
  \ganttbar{Documentation}{10}{14} \\

  % Milestones
  \ganttmilestone{Design Review}{4} \\
  \ganttmilestone{Beta Release}{10} \\
  \ganttmilestone{Launch}{13} \\

  % Dependencies
  \ganttlink{elem0}{elem1}
  \ganttlink{elem1}{elem2}
  \ganttlink{elem2}{elem3}
  \ganttlink{elem3}{elem4}

\end{ganttchart}

Gantt with Groups and Colors

\begin{ganttchart}[
  hgrid,
  vgrid={*{6}{draw=none}, dotted},
  x unit=0.6cm,
  bar/.append style={fill=cyan!40},
  group/.append style={fill=gray!60},
  milestone/.append style={fill=orange!80}
]{1}{24}

  \gantttitle{Q1 2026}{8}
  \gantttitle{Q2 2026}{8}
  \gantttitle{Q3 2026}{8} \\

  \gantttitlelist{Jan,...,Sep}{1} \\

  % Phase 1
  \ganttgroup{Phase 1: Foundation}{1}{8} \\
  \ganttbar[bar/.append style={fill=blue!40}]{Architecture}{1}{3} \\
  \ganttbar[bar/.append style={fill=blue!40}]{Database Design}{2}{5} \\
  \ganttbar[bar/.append style={fill=blue!40}]{API Design}{3}{6} \\
  \ganttmilestone{Phase 1 Complete}{8} \\

  % Phase 2
  \ganttgroup{Phase 2: Development}{7}{18} \\
  \ganttbar[bar/.append style={fill=green!40}]{Backend}{7}{14} \\
  \ganttbar[bar/.append style={fill=green!40}]{Frontend}{9}{16} \\
  \ganttbar[bar/.append style={fill=green!40}]{Integration}{14}{18} \\
  \ganttmilestone{Beta Release}{18} \\

  % Phase 3
  \ganttgroup{Phase 3: Launch}{17}{24} \\
  \ganttbar[bar/.append style={fill=orange!40}]{Testing}{17}{21} \\
  \ganttbar[bar/.append style={fill=orange!40}]{Documentation}{19}{22} \\
  \ganttbar[bar/.append style={fill=orange!40}]{Deployment}{22}{24} \\
  \ganttmilestone{Launch}{24}

\end{ganttchart}

Historical Timeline with chronosys

\usepackage{chronosys}

\startchronology[startyear=1960, stopyear=2000,
                 color=blue!30, height=0.7ex]
\chronoevent{1969}{Unix}
\chronoevent{1972}{C Language}
\chronoevent{1983}{GNU Project}
\chronoevent{1991}{Linux}
\chronoevent{1995}{Java}
\stopchronology

Timeline with Annotations

\usetikzlibrary{decorations.pathreplacing, calligraphy}

\begin{tikzpicture}[scale=0.9]
  % Timeline
  \draw[ultra thick, ->] (0,0) -- (14,0);

  % Periods (colored spans)
  \fill[blue!20]  (0,-0.3) rectangle (4,0.3);
  \fill[green!20] (4,-0.3) rectangle (9,0.3);
  \fill[red!20]   (9,-0.3) rectangle (13,0.3);

  % Period labels
  \node[font=\small\bfseries] at (2,0)   {Early Stage};
  \node[font=\small\bfseries] at (6.5,0) {Growth Stage};
  \node[font=\small\bfseries] at (11,0)  {Mature Stage};

  % Year markers
  \foreach \x/\yr in {0/2018, 4/2020, 9/2022, 13/2024} {
    \draw (\x, 0.4) -- (\x, -0.4);
    \node[below, font=\footnotesize] at (\x, -0.4) {\yr};
  }

  % Key events with annotations
  \draw[thick, ->] (2, 0.5) -- (2, 1.2);
  \node[above, font=\small, text width=2cm, align=center] at (2, 1.2)
    {Product\\Launch};

  \draw[thick, ->] (6, 0.5) -- (6, 1.2);
  \node[above, font=\small, text width=2cm, align=center] at (6, 1.2)
    {1M Users};

  \draw[thick, ->] (11, 0.5) -- (11, 1.2);
  \node[above, font=\small, text width=2cm, align=center] at (11, 1.2)
    {IPO};
\end{tikzpicture}

Swimlane Timeline

For showing parallel tracks:

\begin{tikzpicture}[scale=0.8]
  % Axes
  \draw[->] (0,0) -- (12,0) node[right] {Time};

  % Swimlane labels
  \node[left, font=\small\bfseries] at (0, 1)   {Frontend};
  \node[left, font=\small\bfseries] at (0, 0)   {Backend};
  \node[left, font=\small\bfseries] at (0, -1)  {DevOps};

  % Horizontal lane dividers
  \draw[gray!40, dashed] (0, 0.5) -- (12, 0.5);
  \draw[gray!40, dashed] (0, -0.5) -- (12, -0.5);

  % Frontend tasks
  \fill[blue!30]  (1, 0.6) rectangle (4, 1.4) node[midway, font=\tiny] {UI Design};
  \fill[blue!50]  (3, 0.6) rectangle (8, 1.4) node[midway, font=\tiny] {Development};
  \fill[blue!70]  (7, 0.6) rectangle (10, 1.4) node[midway, font=\tiny] {Testing};

  % Backend tasks
  \fill[green!30] (1, -0.4) rectangle (3, 0.4) node[midway, font=\tiny] {API Design};
  \fill[green!50] (2, -0.4) rectangle (7, 0.4) node[midway, font=\tiny] {Development};
  \fill[green!70] (6, -0.4) rectangle (9, 0.4) node[midway, font=\tiny] {Testing};

  % DevOps tasks
  \fill[red!30]   (1, -1.4) rectangle (2, -0.6) node[midway, font=\tiny] {Setup};
  \fill[red!50]   (8, -1.4) rectangle (10, -0.6) node[midway, font=\tiny] {Deploy};
  \fill[red!70]   (10, -1.4) rectangle (11, -0.6) node[midway, font=\tiny] {Monitor};
\end{tikzpicture}

Packages Summary

Package Best For Complexity
tikz (manual) Custom timelines, full control High
pgfgantt Project Gantt charts Medium
chronosys Historical timelines Low
timeline Simple horizontal timelines Low

Resources

Comments

👍 Was this article helpful?