1

how can I add custom annotations to each bar in a grouped bar chart?
I know how to display the values from the the bars (with every node near...), but the values I need to display, above or below the bars, are others. And, if possible, rotate them by 90 degrees.

E.g. the first first bar in the first group should get the annotation (13/21)

So far i got this working:

\begin{tikzpicture}
    \begin{axis}[
        width  = \textwidth,
        height = 9cm,
        major x tick style = transparent,
        ybar=2*\pgflinewidth,
        bar width=14pt,
        ymajorgrids = true,
        grid style={dashed},
        scaled y ticks = false,
        ylabel = {y},
        xlabel = {x},
        symbolic x coords={1,2,3},
        xticklabels={$1$,$2$,$3$},
        xtick = data,
        enlarge x limits=0.3,
        ymin=-3, ymax=3,
        legend style={
            at={(0.5,-0.2)},
            anchor=north,
            column sep=1ex
        },
        legend columns=2,
        legend cell align=left,
    ]

    \addlegendimage{empty legend}
    \addlegendentry{$n = 3$}
    \addlegendimage{empty legend}
    \addlegendentry{}

    \addplot[style={blue,fill=blue,mark=none}]coordinates {(1, 0.714) (2, 1.211) (3, 2.047) };
    \addlegendentry{type 1}
    \addplot[style={gray,fill=gray,mark=none}]coordinates {(1, 1.276) (2, 1.748) (3, 2.249) };
    \addlegendentry{type 2}
    \addplot[style={red,fill=red,mark=none}]coordinates {(1, 2.25) (2, 1.58) (3, 2.499)};
    \addlegendentry{type 3}
    \addplot[style={green,fill=green,mark=none}]coordinates {(1, 1.666) (2, 1.776) (3, 2.499) };
    \addlegendentry{type 4}
    \addplot[style={yellow,fill=yellow,mark=none}]coordinates {(1, 1.2) (2, 1.14) (3, 1.999) };
    \addlegendentry{type 5}
    \addplot[style={black,fill=black,mark=none}]coordinates {(1, 0.2) (2, 0.598) (3, 1.599) };
    \addlegendentry{type 6} 

    \end{axis}
\end{tikzpicture}
1

As a more principled approach, it turns out that the first solution from How to mark/label nth data point from file in pgfplots? also works for bar plots. The nice thing is that the xshift is taken care of automatically.

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.11}
\pgfplotsset{
    node near coord/.style args={#1/#2/#3}{% Style for activating the label for a single coordinate
        nodes near coords*={
            \ifnum\coordindex=#1 #2\fi
        },
        scatter/@pre marker code/.append code={
            \ifnum\coordindex=#1 \pgfplotsset{every node near coord/.append style=#3}\fi
        }
    },
    nodes near some coords/.style={ % Style for activating the label for a list of coordinates
        scatter/@pre marker code/.code={},% Reset the default scatter style, so we don't get coloured markers
        scatter/@post marker code/.code={},% 
        node near coord/.list={#1} % Run "node near coord" once for every element in the list
    }
}
\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        width  = \textwidth,
        height = 9cm,
        major x tick style = transparent,
        ybar=2*\pgflinewidth,
        bar width=14pt,
        ymajorgrids = true,
        grid style={dashed},
        scaled y ticks = false,
        ylabel = {y},
        xlabel = {x},
        symbolic x coords={1,2,3},
        xticklabels={$1$,$2$,$3$},
        xtick = data,
        enlarge x limits=0.3,
        ymin=-3, ymax=3,
        legend style={
            at={(0.5,-0.2)},
            anchor=north,
            column sep=1ex
        },
        legend columns=2,
        legend cell align=left,
    ]

    \addlegendimage{empty legend}
    \addlegendentry{$n = 3$}
    \addlegendimage{empty legend}
    \addlegendentry{}

    \addplot[style={blue,fill=blue,mark=none},
    nodes near some coords={0/{(13/21)}/above,2/{(17/12)}/above}
    ]coordinates {(1, 0.714) (2, 1.211) (3, 2.047) };
    \addlegendentry{type 1}
    \addplot[style={gray,fill=gray,mark=none}]coordinates {(1, 1.276) (2, 1.748) (3, 2.249) };
    \addlegendentry{type 2}
    \addplot[style={red,fill=red,mark=none}]coordinates {(1, 2.25) (2, 1.58) (3, 2.499)};
    \addlegendentry{type 3}
    \addplot[style={green,fill=green,mark=none}]coordinates {(1, 1.666) (2, 1.776) (3, 2.499) };
    \addlegendentry{type 4}
    \addplot[style={yellow,fill=yellow,mark=none}]coordinates {(1, 1.2) (2, 1.14) (3, 1.999) };
    \addlegendentry{type 5}
    \addplot[style={black,fill=black,mark=none}]coordinates {(1, 0.2) (2, 0.598) (3, 1.599) };
    \addlegendentry{type 6} 
    \end{axis}
\end{tikzpicture}
\end{document}

Output

  • Thats perfect! I rotated my annotations with the rotatebox and reduced the font-size. But on the third group, my annotations overlap with the chart-box. image Is there any possibility to change that? I couldn't find any solution... – baam Nov 22 '15 at 10:44
  • found it: added enlarge y limits={upper,value=0.1} to the settings, and now it looks perfect! – baam Nov 22 '15 at 10:47
1

Combining the two questions Annotate grouped bar plot and How to mark/label nth data point from file in pgfplots?, I figured out two possibilities: Either, you add nodes to the end of each \addplot command (before the semi-colon; see the second link above for more information about pos=), like:

\addplot[style={blue,fill=blue,mark=none}]coordinates {(1, 0.714) (2, 1.211) (3, 2.047) }
node[pos=0.0,xshift=-2.5*\pgfkeysvalueof{/pgf/bar width},anchor=south] {13/21}
node[pos=0.5,xshift=-2.5*\pgfkeysvalueof{/pgf/bar width},anchor=south] {13/21}
node[pos=1.0,xshift=-2.5*\pgfkeysvalueof{/pgf/bar width},anchor=south] {13/21};

Solution 1

Or you add the nodes at the end:

\node[xshift=-2.5*\pgfkeysvalueof{/pgf/bar width},anchor=south] at (axis cs:1,0.714) {13/21};

Solution 2

The advantage of the second solution: Since the labels are added at the end, they are printed above all bars. The advantage of the first solution: You don't need to repeat the y coordinates. In the end, maybe you want to shift the y coordinates in any way, to not have the label interfere with the bars? This should be possible with yshift (or by specifying another y coordinate in the second solution). Note also that in the first solution, the style of the node is the style of the data series (blue in this case).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.