7

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:

enter image description here

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 \%,%
        ]%
\addplot+[%
    color=black,%
    error bars/.cd,%
    y dir=both,%
    y explicit,%
        ]%
table[%
    y error=err%
        ] {barexample.txt};%

\addplot[black, sharp plot]%
    coordinates {(A,50) (D,50)}%
    node[above] at (150,500) {***}%
    ;%

\addplot[black, sharp plot]%
    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.

Thank you for your help!

  • 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
2

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}

\pgfplotstableread{barexample.txt}\myresult
\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}

\pgfplotstableread{barexample.txt}\myresult
\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     
       }% 
      }
    ]
\addplot+[%
    color=black, %
    fill=white,%
    error bars/.cd,%
    y dir=both,%
    y explicit,%
        ]%
table[%
    y error=err%
        ] {barexample.txt};             
\end{axis}%
\end{tikzpicture}%

\end{document}

enter image description here

  • 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

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.