[Tex/LaTex] How to apply “nodes near coords” to a single bar

nodes-near-coordspgfplots

I want to change the position of a single node in a ybar plot. I know I am able to change the position of the nodes for a whole plot (by adding nodes near coords in the \addplot [...]), but in this case this is undesired.

As one can see in the image, the 7 needs to be in a different position in order to not be crossed out by the target line. Is there a simple way to this or do need to manually remove the number by overdrawing it and add another node? Of course, one could upshift all numbers but this is looks strange as well.

enter image description here

Bonus question: If there is way to automatically determine the x position (in case of ybar>0) and length of the target bars, I would be glad to know.

MWE

\documentclass{standalone}

\usepackage{tikz}
\usepackage{pgfplots,pgfplotstable}

\begin{document}

\begin{tikzpicture}
\begin{axis}[
    x tick label style={/pgf/number format/1000 sep=},
    xtick={2000, 2001, 2002},
    enlarge x limits=0.45,
    ybar=0pt,
    bar width=10,
    nodes near coords={\pgfmathprintnumber[fixed,fixed zerofill,precision=0]{\pgfplotspointmeta}},
]

\addplot 
    coordinates {(2000,1) (2001,5) (2002,7)};

\addplot 
    coordinates {(2000,2) (2001,4) (2002,9)};

\draw[blue, very thick] (axis cs:2002-0.0,7.5) -- (axis cs:2002-0.19    ,7.5) node[anchor=east] {target};   
\draw[red, very thick] (axis cs:2002+0.0,8.0) -- (axis cs:2002+0.19,8.0) node[anchor=west] {target};


\end{axis}
\end{tikzpicture}

\end{document}

Best Answer

Here's an approach taking into consideration your bonus question. The values for ybar and bar width are defined outside the axis options (\ybarval and \barwidthval, respectively) to allow for easy retrieval. The options for the first plot are ammended to add a conditional to the nodes near coords which will not add a node for the second coordinate. The shifted label is then added manually, with the y coordinate equal to that of the target value for consistent spacing (yshift= with the y coordinate of 7 would be another approach). The x coordinate is shifted to account for \ybarval and \barwidthval.

The target lines and nodes are determined semi-automatically using the let notation from the calc library.

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{pgfplots,pgfplotstable}

\newcommand\ybarval{5pt}%ybar value
\newcommand\barwidthval{10}%bar width value

\begin{document}

\begin{tikzpicture}
\begin{axis}[
    x tick label style={/pgf/number format/1000 sep=},
    xtick={2000, 2001, 2002},
    enlarge x limits=0.45,
    ybar=\ybarval,
    bar width=\barwidthval,
    nodes near coords={\pgfmathprintnumber[fixed,fixed zerofill,precision=0]{\pgfplotspointmeta}},
]

\addplot +[nodes near coords={\ifnum\coordindex=2\else{\pgfmathprintnumber[fixed,fixed zerofill,precision=0]{\pgfplotspointmeta}}\fi}]%will not write the label for the second coordinate
    coordinates {(2000,1) (2001,5) (2002,7)};

\addplot 
    coordinates {(2000,2) (2001,4) (2002,9)};

%manual node addition for second coordinate
\node [blue, above, xshift=-0.5*\barwidthval-0.5*\ybarval] at (axis cs: 2002,7.5) {7};

%semi-automatic target lines
\draw[blue, very thick] let \p1=(axis cs:2002,7.5) in (\x1-0.5*\ybarval,\y1)--(\x1-\barwidthval-0.5*\ybarval,\y1)node[anchor=east] {target};
\draw[red, very thick] let \p1=(axis cs:2002,8.0) in (\x1+0.5*\ybarval,\y1)--(\x1+\barwidthval+0.5*\ybarval,\y1) node[anchor=west] {target};

\end{axis}
\end{tikzpicture}
\end{document}

result

Limitations: Some manual adjustment would be required if additional plots were added. Also, this approach doesn't generalize well for more than one conflicting label in a plot.