3

I'm trying to make a bar chart with pgfplots. I'd like the labels to be plotted inside the bars, except when there is not enough space. In that case the label should be shown next to the bar.

I've included some code to reproduce the chart i'm making. With percentages under 3% there is not enough space to align the node left. For those nodes i'd like it to align right. The data file data.dat will be generated from outside latex and data values may differ in future, so i'm looking for a general solution. Any help would be very much appreciated.

\documentclass[a4paper, 9pt]{report}
\usepackage{filecontents} 
\usepackage{pgfplots, pgfplotstable}
\begin{document}
\begin{filecontents}{data.dat}
rownum value value2 label
1 10 1.1 Cluster~A
2 14 6 Cluster~B
3 17 7 Cluster~C
4 15 2.2 Cluster~D
5 19 4 Cluster~E
6 18 11 Cluster~F
\end{filecontents}
\begin{figure}[h]
\caption{A caption.}
\begin{tikzpicture}
  \begin{axis}[
    xbar,
    y dir=reverse,
    axis y line*=none, 
    axis x line*=none,
    major tick length=0,
    xmin=0,
    xmax=50,
    enlarge x limits={abs=0.00005},
    scale only axis, width=10cm,
    ytick={1,...,6},
    xtick={0, 10, ..., 50},
    xticklabel=\pgfmathprintnumber{\tick}\,\%,
    yticklabel style={text width=3cm, align=right},
    yticklabels from table={data.dat}{label},
    xmajorgrids,
    major grid style={black},
    tick style={black},
    bar width=4mm,
    y=12mm, 
    enlarge y limits={abs=0.6}, 
    nodes near coords={\pgfmathprintnumber[precision=0]\pgfplotspointmeta\%},
    nodes near coords align=left
  ]
  \addplot [draw=lime , fill=lime] table [x=value, y=rownum] {data.dat}; 
  \addplot [draw=orange , fill=orange] table [x=value2, y=rownum] {data.dat}; 
  \end{axis}
\end{tikzpicture}
\end{figure}
\end{document}
3

You can check whether the value is less than 3 using the key visualization depends on={meta < 3 \as \valueissmall}, and then use the result of that comparison to set the anchor of your label (note the use of \ifdim and the need for the pt after the values):

every node near coord/.append style={
    anchor={\ifdim\valueissmall pt=1 pt west\else east\fi}
}

\documentclass[a4paper, 9pt]{report}
\usepackage{filecontents} 
\usepackage{pgfplots, pgfplotstable}
\begin{document}
\begin{filecontents}{data.dat}
rownum value value2 label
1 10 1.1 Cluster~A
2 14 6 Cluster~B
3 17 7 Cluster~C
4 15 2.2 Cluster~D
5 19 4 Cluster~E
6 18 11 Cluster~F
\end{filecontents}
\begin{figure}[h]
\caption{A caption.}
\begin{tikzpicture}
  \begin{axis}[
    xbar,
    y dir=reverse,
    axis y line*=none, 
    axis x line*=none,
    major tick length=0,
    xmin=0,
    xmax=50,
    enlarge x limits={abs=0.00005},
    scale only axis, width=10cm,
    ytick={1,...,6},
    xtick={0, 10, ..., 50},
    xticklabel=\pgfmathprintnumber{\tick}\,\%,
    yticklabel style={text width=3cm, align=right},
    yticklabels from table={data.dat}{label},
    xmajorgrids,
    major grid style={black},
    tick style={black},
    bar width=4mm,
    y=12mm, 
    enlarge y limits={abs=0.6}, 
    nodes near coords={\pgfmathprintnumber[precision=0]\pgfplotspointmeta\%},
    visualization depends on={meta < 3 \as \valueissmall},
    every node near coord/.append style={
            anchor={\ifdim\valueissmall pt=1 pt west\else east\fi}
        }
  ]
  \addplot [draw=lime , fill=lime] table [x=value, y=rownum] {data.dat}; 
  \addplot [draw=orange , fill=orange] table [x=value2, y=rownum] {data.dat}; 
  \end{axis}
\end{tikzpicture}
\end{figure}
\end{document}

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.