# Displaying significance of results in pgfplots by lines with asteriks

after searching for some time without finding a satisfying answer, I finally decided to post my first question. Using the search function, I found simmilar questions, but non of the answer given there where satisfying either.

My problem: I am using pgfplots to display results in bar graphs and tested the data for significant differences by ANOVA and Dunnett's Multiple Comparison Test vs. one control. I would like to have something, that looks like this:

I produced this using the following code:

\documentclass{scrartcl}%
\usepackage[T1]{fontenc}%
\usepackage[utf8]{inputenc}%
\usepackage[ngerman]{babel}%

\usepackage{amsmath}%
\usepackage{tikz}%
\usepackage{pgfplots}%
\pgfplotsset{width=7cm,compat=1.7}%

\begin{document}%
\begin{tikzpicture}%
\begin{axis}[%
ybar,%
title=Test,%
axis y line=left, axis x line*=bottom,%
ymin=0, ymax=70,%
x tick label style={rotate=45,anchor=east},%
symbolic x coords={A, B, C, D, E},%
ylabel=difference in \%,%
]%
color=black,%
error bars/.cd,%
y dir=both,%
y explicit,%
]%
table[%
y error=err%
] {barexample.txt};%

coordinates {(A,50) (D,50)}%
node[above] at (150,500) {***}%
;%

coordinates {(A,60) (E,60)}%
node[above] at (150,600) {**}%
;%
\end{axis}%
\end{tikzpicture}%
\end{document}%


This ist the content of the datafile:

xval    yval    err     sig
A       1       0.2     control
B       10      2.5     n.s.
C       20      2.2     n.s.
D       40      4.2     ***
E       28      2.8     **


I am looking for a solution, that would check the sig collum for the asteriks and given the case there are *** or ** or * draws a line above the colums and inserts the appropriated numer of * at a certain position of the line. In addition, lines should be stacked, starting with the far right on top and so on.

• – Jake Aug 24 '15 at 14:21
• Thx @Jake, I know this topic, the answer just doesn't help to solve my problem (see pic). This would be a last chance solution. – pharmarkus Aug 24 '15 at 14:24
• Sure, I intended the link mainly for other people who find this question looking to mark significant bars using asterisks. Regarding your question: could you elaborate on what you mean by "lines should be stacked"? Also, the groups of asterisks both seem to be at the same horizontal position, not above the bar that they refer to. Is this intentional? – Jake Aug 24 '15 at 14:28
• Sure, by stacked I meant that the line and asteriks complexes should have the same distance toward the next complex. About the positioning I am not quite sure, wheter I want them aligned horizontally or centered on the line. I have seen both in papers and I am kinda torn. – pharmarkus Aug 24 '15 at 14:34

You can use the after end axis/.code option and a foreach loop to read the file line by line. The maximum number of lines, asterisks and the maximum y-value are calculated using pgfplotstable.

\maxvalue{barexample.txt}{yval}
\maxasterisk{barexample.txt}{sig}

\pgfplotstablegetrowsof{\myresult}
\pgfmathsetmacro{\N}{\pgfplotsretval-1}


You can use a very nice solution from this answer to check if your column contains an asterisk.

\documentclass{scrartcl}%
\usepackage[T1]{fontenc}%
\usepackage[utf8]{inputenc}%
\usepackage[ngerman]{babel}%

\usepackage{amsmath}%
\usepackage{tikz}%
\usepackage{pgfplots}%
\pgfplotsset{width=7cm,compat=1.7}%
\usepackage{pgfplotstable}
\usepackage{xstring}

\newcommand{\maxvalue}[2]{
\pgfplotstablesort[sort key={#2},sort cmp={float >}]{\result}{#1}
\pgfplotstablegetelem{0}{#2}\of{\result}
\let\ymax=\pgfplotsretval
}

\newcommand{\maxasterisk}[2]{
\pgfplotstablesort[sort cmp=string <]\result{#1}
\pgfplotstablegetelem{0}{#2}\of{\result}
\StrLen{\pgfplotsretval}[\ast]
\let\astmax=\ast
}

\makeatletter
\def\instring#1#2{TT\fi\begingroup
\edef\x{\endgroup\noexpand\in@{#1}{#2}}\x\ifin@}
\makeatother

\begin{document}

\maxvalue{barexample.txt}{yval}
\maxasterisk{barexample.txt}{sig}

\pgfplotstablegetrowsof{\myresult}
\pgfmathsetmacro{\N}{\pgfplotsretval-1}

\begin{tikzpicture}%
\begin{axis}[%
ybar,%
title=Test,%
axis y line=left, axis x line*=bottom,%
ymin=0, ymax=\ymax+\astmax*5,%
x tick label style={rotate=45,anchor=east},%
symbolic x coords={A, B, C, D, E},%
ylabel=difference in \%,
after end axis/.code={
\foreach \i in {0,...,\N}{
\pgfplotstablegetelem{\i}{[index] 3}\of\myresult
\let\curr\pgfplotsretval
\pgfplotstablegetelem{\i}{[index] 0}\of\myresult
\let\currid\pgfplotsretval
\if\instring{*}{\curr}
\StrLen{\curr}[\currast]
\pgfmathsetmacro{\yvalue}{\ymax+(\i+1)*5}
\draw ([yshift=-1mm]axis cs:A,\yvalue) -- (axis cs:A,\yvalue) -- node[above, yshift=-2mm]{\small\curr} (axis cs:\currid,\yvalue) -- ([yshift=-1mm]axis cs:\currid,\yvalue);
\fi
}%
}
]
color=black, %
fill=white,%
error bars/.cd,%
y dir=both,%
y explicit,%
]%
table[%
y error=err%
] {barexample.txt};
\end{axis}%
\end{tikzpicture}%

\end{document}


• Thank you for the code. The result is pretty cool, but still doesn't really hit it. – pharmarkus Aug 25 '15 at 11:46
• I've edited my answer. – SLx64 Aug 25 '15 at 18:59
• Pretty cool and exactly, what I was looking for! Thx – pharmarkus Aug 26 '15 at 6:40