Bar charts in LaTeX with TikZ

I have four systems to compare (baseline, minimal, window, syntax) on three different tasks (let’s call them PI, AI and AC). I want a bar chart (similar to this example). We of course use TikZ and pgfplots and there is ybar to get a bar chart. The outer bars are cut off, so we need to add a little space on both sides with enlarge x limits. We can play around with the axes, the height and the width of the plot and the legend, but you can look at other examples for this, I’ll focus on two things here.

First, I would like to have the three tasks side by side with a nice name. In TikZ we can use symbolic x coordinates for this, we just give them some names and can then use them like any other x coordinate, e.g., to put a data point at (PI, 50). We can give the coordinates labels that are nicer to read with xticklabels. Usually there will be ‘ticks’ (i.e., markers on the x axis) somewhere randomly, to get only for each x-axis label/task, use xtick=data.

symbolic x coords={PI, AI, AC},
xticklabels={Pred. ident., Arg. ident., Arg. class.},
xtick=data,

Second, I would like to have the numbers above the bars with one decimal place. We can get the numbers with these two lines (the first one gives the numbers, as they are too big the second line adjusts the font size):

nodes near coords={\pgfmathprintnumber[fixed zerofill,fixed,precision=1]{\pgfplotspointmeta}}
every node near coord/.append style={font=\tiny}

To get rid of zeros, we can replace the second line with

every node near coord/.append style={
      check for zero/.code={
        \pgfmathfloatifflags{\pgfplotspointmeta}{0}{
           \pgfkeys{/tikz/coordinate}
        }{}
      }, 
      check for zero, font=\tiny},

So this is my final axis style:

\pgfplotsset{resultsplot/.style={
axis x line*=bottom, 
axis y line=left, 
ybar,
symbolic x coords={PI, AI, AC},
xticklabels={Pred. ident., Arg. ident., Arg. class.},
xtick=data,
enlarge x limits=0.2,
nodes near coords={\pgfmathprintnumber[fixed zerofill,fixed,precision=1]{\pgfplotspointmeta}},
every node near coord/.append style={
      check for zero/.code={
        \pgfmathfloatifflags{\pgfplotspointmeta}{0}{
           \pgfkeys{/tikz/coordinate}
        }{}
      }, check for zero, font=\tiny},
area legend,
legend style={at={(0.5,-0.12)},
anchor=north,legend columns=-1},
}
}

And now we can get the actual graph that uses this axis style. Each plot represents a different system (the numbers are F1 scores):

 
\begin{tikzpicture}
\begin{axis}[resultsplot]
\addplot+ [ybar,green] coordinates {(PI, 67.8) (AI, 30.6) (AC, 20.2)};
\addlegendentry{Baseline}
\addplot+ [ybar,blue] coordinates {(PI, 78.6) (AI, 21.2) (AC, 16.5)};
\addlegendentry{Minimal system}
\addplot+ [ybar,orange] coordinates {(PI, 80.0) (AI, 44.2) (AC, 36.6)};
\addlegendentry{Window}
\addplot+ [ybar,red] coordinates {(PI, 80.1) (AI, 54.2) (AC, 44.8)};
\addlegendentry{Syntax}
\end{axis}
\end{tikzpicture}

Have fun!

This entry was posted in LaTeX and tagged , , , by swk. Bookmark the permalink.

About swk

I am a software developr, data scientist, computational linguist, teacher of computer science and above all a huge fan of LaTeX. I use LaTeX for everything, including things you never wanted to do with LaTeX. My latest love is lilypond, aka LaTeX for music. I'll post at irregular intervals about cool stuff, stupid hacks and annoying settings I want to remember for the future.