8

I'm showing several data sets next to each other using multiple \addplot commands within a pgfplots axis environment. These are then further grouped into categories. The output of the graph per se is fine, however, I need each bar to be labelled separately - basically, I want the legend to be displayed directly underneath its corresponding element. I presume a picture will illustrate my problem more clearly:

enter image description here

I prepared an MWE:

\documentclass{minimal}
\usepackage{pgfplots}

\begin{document}

\pgfplotstableread{
0 35569 8842    134984  
1 30428 4689    34077
2 32920 6207    73787   
3 16462 7562    23496   
4 12315 8572    16565   
5 76572 19572   26030   
}\dataset
\begin{tikzpicture}
\begin{axis}[ybar,
        width=.9\textwidth,
        ymin=0,
        ymax=150000,        
        ylabel={Y-Label},
        xtick=data,
        xticklabels = {
            Category 1,
            Category 2,
            Category 3,
            Category 4,
            Category 5,
            Category 6
        },
        major x tick style = {opacity=0},
        minor x tick num = 1,
        minor tick length=2ex,
        ]
\addplot[draw=black,fill=black!20] table[x index=0,y index=1] \dataset; %Data1
\addplot[draw=black,fill=black!40] table[x index=0,y index=2] \dataset; %Data2
\addplot[draw=black,fill=black!60] table[x index=0,y index=3] \dataset; %Data3
\legend{Data1,Data2,Data3}
\end{axis}
 \end{tikzpicture}

\end{document}
1
11

You can adapt the method from Center nodes near coords in a stacked ybar plot to use nodes near coords for the labels:

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}

\begin{document}
\makeatletter
\pgfplotsset{
    calculate offset/.code={
        \pgfkeys{/pgf/fpu=true,/pgf/fpu/output format=fixed}
        \pgfmathsetmacro\testmacro{(\pgfplotspointmeta *10^\pgfplots@data@scale@trafo@EXPONENT@y)*\pgfplots@y@veclength)}
        \pgfkeys{/pgf/fpu=false}
    },
    every node near coord/.style={
        /pgfplots/calculate offset,
        yshift=-\testmacro
    },
}
\pgfplotstableread{
0 35569 8842    134984  
1 30428 4689    34077
2 32920 6207    73787   
3 16462 7562    23496   
4 12315 8572    16565   
5 76572 19572   26030   
}\dataset
\begin{tikzpicture}
\begin{axis}[ybar,
        width=15cm,
        height=8cm,
        ymin=0,
        ymax=150000,        
        ylabel={Y-Label},
        xtick=data,
        xticklabels = {
            Category 1,
            Category 2,
            Category 3,
            Category 4,
            Category 5,
            Category 6
        },
        xticklabel style={yshift=-8ex},
        major x tick style = {opacity=0},
        minor x tick num = 1,
        minor tick length=2ex,
        every node near coord/.append style={
                anchor=east,
                rotate=90
        }
        ]
\addplot[draw=black,fill=black!20, nodes near coords=Data 1] table[x index=0,y index=1] \dataset; %Data1
\addplot[draw=black,fill=black!40, nodes near coords=Data 2] table[x index=0,y index=2] \dataset; %Data2
\addplot[draw=black,fill=black!60, nodes near coords=Data 3] table[x index=0,y index=3] \dataset; %Data3
\end{axis}
 \end{tikzpicture}

\end{document}
0
2

At least in the meantime there is a solution to achieve the desired result without makeatletter "hackery".

For details please have a look at the comments in the code.

% used PGFPlots v1.16
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
    \pgfplotsset{
        compat=1.3,
    }
    \pgfplotstableread{
        0 35569 8842    134984
        1 30428 4689    34077
        2 32920 6207    73787
        3 16462 7562    23496
        4 12315 8572    16565
        5 76572 19572   26030
    }\dataset
\begin{document}
\begin{tikzpicture}
    \begin{axis}[
        width=15cm,
        height=8cm,
        ymin=0,
        ymax=150000,
        ybar,
        ylabel={Y-Label},
        xtick=data,
        xticklabels={
            Category 1,
            Category 2,
            Category 3,
            Category 4,
            Category 5,
            Category 6
        },
        xticklabel style={yshift=-8ex},
        major x tick style={
            % (this is a better way than assigning `opacity=0')
            /pgfplots/major tick length=0pt,
        },
        minor x tick num=1,
        minor tick length=2ex,
        % ---------------------------------------------------------------------
        % (adapted solution from <https://tex.stackexchange.com/a/141006/95441>)
        % we want to provide absolute `at' values ...
        scatter/position=absolute,
        node near coords style={
            % ... to provide axis coordinates at `ymin' for the nodes
            at={(axis cs:\pgfkeysvalueof{/data point/x},\pgfkeysvalueof{/pgfplots/ymin})},
            % then also the `anchor' has to be adapted ...
            anchor=east,
            % ... because we rotate the labels which would overlap otherwise
            rotate=90,
        },
        % ---------------------------------------------------------------------
        % (created a cycle list to shorten the below `\addplot' entries)
        cycle list={
            {draw=black,fill=black!20},
            {draw=black,fill=black!40},
            {draw=black,fill=black!60},
        },
        % (moved common option here)
        table/x index=0,
    ]
        \addplot+ [nodes near coords=Data 1] table [y index=1] \dataset;
        \addplot+ [nodes near coords=Data 2] table [y index=2] \dataset;
        \addplot+ [nodes near coords=Data 3] table [y index=3] \dataset;
    \end{axis}
\end{tikzpicture}
\end{document}

image showing the result of above code

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.