# Grouped bar chart with horizontal line over every bar

What I want to do:
Put horizontal lines on top of every bar of a grouped bar plot with symbolic x axis coordinates. The lines shall align with the width of each bar. See the 2 example bars with lines in the code and the image below.
Note, that these lines are used to indicate an "upper bound" for each bar. Hence, every line has its own y-coordinate which is independent from the actual height of the bar.
What I have so far:
I only came up with an unsatisfying solution:
Draw simple lines by a \draw call and approximating the x-coordinates by hand.
Why is this a problem?
This leads to the very ugly "magic" numbers (e.g. !.655!, !.862!) for the x-coordinate calculation as you can see in the code below. This becomes very tedious since I have many bars and the number of bars per group may change.
What is missing to solve my problem?
I am looking for a more convenient way to calculate (or get) the min/max x-coordinates of the individual bars. With these coordinates which are indicated with black ticks in the image below, I can easily draw the desired lines.

My current approach is based on the following MWE:

\documentclass[11pt]{standalone}

\usepackage{tikz}
\usetikzlibrary{calc}

\usepackage{pgfplots}

\begin{document}

\begin{tikzpicture}
\begin{axis}[
ybar,
enlargelimits=0.15,
ylabel={index},
symbolic x coords={1982, 1990, 1999, 2006},
legend style={at={(0.5,-0.15)},
anchor=north,legend columns=-1},
]

\addplot coordinates {(1982, 1.78) (1990, 1.71) (1999, 1.68) (2006, 1.62)};
\addplot coordinates {(1982,  1.70) (1990, 1.62) (1999, 1.59) (2006, 1.64)};
\addplot coordinates {(1982, 2.04) (1990, 1.96) (1999, 1.95) (2006, 1.91)};

\draw[blue, thick] ($(axis cs:1982, 1.72)!.655!(axis cs:1990, 1.72)$) -- ($(axis cs:1982, 1.72)!.862!(axis cs:1990, 1.72)$);
\draw[red , thick] ($(axis cs:1982, 1.68)!.89!(axis cs:1990, 1.68)$) -- ($(axis cs:1990, 1.68)!.115!(axis cs:1999, 1.68)$);

\legend{USA, Netherlands, {(West-)Germany}}

\end{axis}
\end{tikzpicture}

\end{document}


Any help is very appreciated.

edit: clarified question.

• sorry, your question is unclear. what you like to acieve? numbers with $\overline$ on top of bars?. for conviniece, please provide code what you try so far (by which the plot in your question has been generated). Feb 11 '18 at 1:11

So you are searching for something like the following?
For details please have a look at the comments of the code.

% used PGFPlots v1.15
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.3}
% move data to a table
% add columns for error bars and state "NaN" where no bar should be shown
x       y1      y2      y3      y1err   y2err
1982    1.78    1.70    2.04    NaN     NaN
1990    1.71    1.62    1.96    0.05    0.02
1999    1.68    1.59    1.95    NaN     NaN
2006    1.62    1.64    1.91    NaN     NaN
\begin{document}
\begin{tikzpicture}
\begin{axis}[
ybar,
ylabel={index},
% so you don't have to repeat the "x" data, replace the commented line
% by the next two
% (this only works if the first \addplot' command has data points on
%  all x coordinates)
%        symbolic x coords={1982, 1990, 1999, 2006},
xtick=data,
enlargelimits=0.15,
legend style={
at={(0.5,-0.15)},
anchor=north,
legend columns=-1,
},
% ---
% moved common options here
% ---
% this is also needed for the replacement of symbolic x coords'
table/x expr=\coordindex,
% now we add the horizontal lines
error bars/y dir=plus,
error bars/y explicit,
% (inspired by <https://tex.stackexchange.com/a/19962/95441>)
error bars/error bar style={
% don't show the vertical line
opacity=0,
},
% and here the modifications for the horizontal line
error bars/error mark options={
rotate=90,
mark size=0.5*\pgfplotbarwidth,
line width=0.4pt,   % this is the default line with
line cap=rect,
opacity=1,          % to revert the option from error bar style'
},
]

\legend{
USA,
Netherlands,
{(West-)Germany},
}
\end{axis}
\end{tikzpicture}
\end{document}


• Yes, this is pretty much what I was looking for. A lot of error magic was required ;-). I only have minor issue now: my input data does not have these relative error values, but absolute values. For example the line from your dummy table would read like: 1990 1.71 1.62 1.96 1.76 1.64 So I am just gonna add new columns containing the calculated error and then everything should be fine :) Thanks a lot!
– arox
Feb 11 '18 at 12:50
• When you have the absolute/max value you could replace y error=y1err by y error expr=\thisrow{y1err} - \thisrow{y1}, etc. to achieve the desired result. Feb 11 '18 at 13:03

OK, I looked at an older version of your question, for which I propose

\documentclass{article}

\usepackage{pgfplots}

\begin{document}

\begin{tikzpicture}
\begin{axis}[
ybar,
enlargelimits=0.15,
ylabel={index},
symbolic x coords={1982, 1990, 1999, 2006},
%xtick=data,
%tick label style={font=\footnotesize},
legend style={at={(0.5,-0.15)},
anchor=north,legend columns=-1},
nodes near coords,
every node near coord/.append style={font=\tiny},
nodes near coords={\underline{\pgfmathprintnumber{\pgfplotspointmeta}}},
nodes near coords align={vertical},
]
\addplot coordinates {(1982, 1.78) (1990, 1.71) (1999, 1.68) (2006, 1.62)};
\addplot coordinates {(1982,  1.70) (1990, 1.62) (1999, 1.59) (2006, 1.64)};
\addplot coordinates {(1982, 2.04) (1990, 1.96) (1999, 1.95) (2006, 1.91)};
\legend{USA, Netherlands, {(West-)Germany}}

\end{axis}
\end{tikzpicture}

\end{document}


EDIT: OK, now to version 2 (?) of your question:

\documentclass{article}

\usepackage{pgfplots}

\begin{document}

\begin{tikzpicture}
\begin{axis}[
ybar,
bar width=12pt,
enlargelimits=0.15,
ylabel={index},
symbolic x coords={1982, 1990, 1999, 2006},
%xtick=data,
%tick label style={font=\footnotesize},
legend style={at={(0.5,-0.15)},
anchor=north,legend columns=-1},
nodes near coords,
every node near coord/.append style={font=\tiny},
nodes near coords={\rule{12pt}{1pt}},
nodes near coords align={vertical},
]
\addplot coordinates {(1982, 1.78) (1990, 1.71) (1999, 1.68) (2006, 1.62)};
\addplot coordinates {(1982,  1.70) (1990, 1.62) (1999, 1.59) (2006, 1.64)};
\addplot coordinates {(1982, 2.04) (1990, 1.96) (1999, 1.95) (2006, 1.91)};
\legend{USA, Netherlands, {(West-)Germany}}

\end{axis}
\end{tikzpicture}

\end{document}


The lengths of the \rule are chosen to coincide with the bar width`.

• I am sorry for my initially unprecise question.
– arox
Feb 11 '18 at 1:47
• @arox OK, I added the hopefully correct answer.
– user121799
Feb 11 '18 at 1:54
• Thanks again for your help, but I am afraid, its not exactly what I was looking for. I added the following note to my question, which hopefully eliminates further unclarities: "Note, that these lines are used to indicate an "upper bound" for each bar. Hence, every line has its own y-coordinate which is independent from the actual height of the bar."
– arox
Feb 11 '18 at 9:18