3

I need to draw a bar chart based on the data from the file. The data looks something like this

\begin{filecontents*}{tls.dat} 
    Name Abbreviation percentage
    Bod-Kin LS1 60 
Intraper LS2 40
Verb-Ling LS3 20 
Spat-Vis LS4 10
Natur LS5 5 
Interper LS6 0 
Mus LS7 0 
Log-Math LS8 0
\end{filecontents*}

Bar chart involves only rows that have percentage value higher than 0, and it needs to look something like this.

enter image description here

So far I have managed to read the data, have it sorted based on the percentage and I can draw the dynamic bar graphs manually, but I can't scale the length of the bar based on the top values from data.

Here is my MWE.

\documentclass[a4paper]{article}
\usepackage[left=43px,bottom=45.4px,right=46px,top=35px]{geometry}
\usepackage{graphicx}
\usepackage{xcolor}
\usepackage{color}
\usepackage{tikz}
\usepackage{afterpage}
\usetikzlibrary{spy}
\usetikzlibrary{fit,calc,positioning}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{arrows}
\usepackage{filecontents}
\usepackage{pgfplotstable}
\usepackage{ifthen}
\usepackage{readarray}
\usepackage{array}

\begin{filecontents*}{tls.dat} 
    Name Abbreviation percentage
    Bod-Kin LS1 60 
    Intraper LS2 40
    Verb-Ling LS3 20 
    Spat-Vis LS4 10
    Natur LS5 5 
    Interper LS6 0 
    Mus LS7 0 
    Log-Math LS8 0
\end{filecontents*}

\definecolor{backgroundgray}{HTML}{EDEDED}
\definecolor{hashc}{HTML}{00A3E5}

\begin{document}
\newgeometry{top=35px, left=44px, right=43.7px,bottom=60.4px}
\pagecolor{backgroundgray}\afterpage{\nopagecolor}

\newcounter{mya}

%% calculate how many attributes have positive value

\pgfplotstableread[columns={Name,Abbreviation,percentage}]{tls.dat}\datatableA
\pgfplotstablesort[sort key={percentage}, sort cmp=int >]{\datatablesorted}{\datatableA}
\pgfplotstablegetrowsof{\datatablesorted} 
\pgfmathtruncatemacro{\RowsInTable}{\pgfplotsretval-1} 
\pgfmathtruncatemacro{\TotalRows}{\pgfplotsretval} 
 \foreach \k in {0,...,\RowsInTable}{
 \pgfplotstablegetelem{\k}{percentage}\of{\datatablesorted}
 \pgfmathtruncatemacro{\itest}{sign(\pgfplotsretval)}
 \ifnum\itest=1
\stepcounter{mya}
\fi}


\noindent\fcolorbox{white}{white}{
\begin{minipage}[t][]{230px}
\vspace*{15px}
\begin{center}
\fontsize{16px}{30px}\color{gray}\textsl{TLS}
\end{center}
\addtocounter{mya}{-1}
\begin{tikzpicture}
%% draw names of bar plot
\pgfplotstablegetelem{0}{percentage}\of{\datatablesorted}
 \def\maxlength{\pgfplotsretval}

 \foreach \k in {0,...,\value{mya}}{
 \pgfplotstablegetelem{\k}{percentage}\of{\datatablesorted}
 \pgfmathtruncatemacro{\itest}{sign(\pgfplotsretval)}
 \pgfplotstablegetelem{\k}{Abbreviation}\of{\datatablesorted}
 \node at (0,-\k) {\fontsize{12px}{16px}\selectfont\color{gray}\pgfplotsretval};

 %draw bar plots
 \pgfplotstablegetelem{\k}{percentage}\of{\datatablesorted}
 \pgfmathsetmacro\curlength{\pgfplotsretval}
\pgfmathsetmacro\lengthpernodeA{0.9*\curlength / \maxlength}
 \fill [hashc] (0.5,-\k-0.25) rectangle (\lengthpernodeA\textwidth,0.25-\k);
 }

\end{tikzpicture}
\end{minipage}

}

\end{document}

MWE gives me this

enter image description here

1
  • Your code works beautifully if you replace \def\maxlength{\pgfplotsretval} by \edef\maxlength{\pgfplotsretval}. – user121799 Jun 1 '19 at 21:50
2

Apologies for underestimating the question! Let me first explain what went wrong in your code. When you say \def\maxlength{\pgfplotsretval} then \maxlength will be updated when you update \pgfplotsretval. However, if you expand the value, i.e. use \edef\maxlength{\pgfplotsretval} (no, e does not stand for egreg ;-) then it works. This is what the following code does, in which I stripped off packages that are not needed here.

\documentclass[a4paper]{article}
\usepackage[left=43px,bottom=45.4px,right=46px,top=35px]{geometry}
\usepackage{tikz}
\usepackage{afterpage}
\usepackage{filecontents}
\usepackage{pgfplotstable}

\begin{filecontents*}{tls.dat} 
    Name Abbreviation percentage
    Bod-Kin LS1 60 
    Intraper LS2 40
    Verb-Ling LS3 20 
    Spat-Vis LS4 10
    Natur LS5 5 
    Interper LS6 0 
    Mus LS7 0 
    Log-Math LS8 0
\end{filecontents*}

\definecolor{backgroundgray}{HTML}{EDEDED}
\definecolor{hashc}{HTML}{00A3E5}

\begin{document}
\newgeometry{top=35px, left=44px, right=43.7px,bottom=60.4px}
\pagecolor{backgroundgray}\afterpage{\nopagecolor}

\newcounter{mya}

%% calculate how many attributes have positive value

\pgfplotstableread[columns={Name,Abbreviation,percentage}]{tls.dat}\datatableA
\pgfplotstablesort[sort key={percentage}, sort cmp=int >]{\datatablesorted}{\datatableA}
\pgfplotstablegetrowsof{\datatablesorted} 
\pgfmathtruncatemacro{\RowsInTable}{\pgfplotsretval-1} 
\pgfmathtruncatemacro{\TotalRows}{\pgfplotsretval} 
 \foreach \k in {0,...,\RowsInTable}{
 \pgfplotstablegetelem{\k}{percentage}\of{\datatablesorted}
 \pgfmathtruncatemacro{\itest}{sign(\pgfplotsretval)}
 \ifnum\itest=1
\stepcounter{mya}
\fi}


\noindent\fcolorbox{white}{white}{
\begin{minipage}[t][]{230px}
\vspace*{15px}
\begin{center}
\fontsize{16px}{30px}\color{gray}\textsl{TLS}
\end{center}
\addtocounter{mya}{-1}
\begin{tikzpicture}
%% draw names of bar plot
\pgfplotstablegetelem{0}{percentage}\of{\datatablesorted}
 \edef\maxlength{\pgfplotsretval} % <----
 \foreach \k in {0,...,\value{mya}}{
 \pgfplotstablegetelem{\k}{percentage}\of{\datatablesorted}
 \pgfmathtruncatemacro{\itest}{sign(\pgfplotsretval)}
 \pgfplotstablegetelem{\k}{Abbreviation}\of{\datatablesorted}
 \node at (0,-\k) {\fontsize{12px}{16px}\selectfont\color{gray}\pgfplotsretval};

 %draw bar plots
 \pgfplotstablegetelem{\k}{percentage}\of{\datatablesorted}
 \edef\curlength{\pgfplotsretval}
 \pgfmathsetmacro\lengthpernodeA{(0.9*\curlength /\maxlength)}
 \fill [hashc] (0.5,-\k-0.25) rectangle (\lengthpernodeA\textwidth,0.25-\k);
 }

\end{tikzpicture}
\end{minipage}

}
\end{document}

enter image description here

Here is an alternative using an xbar plot of pgfplots. It might be easier to customize.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{filecontents}
\begin{filecontents*}{tls.dat} 
Name Abbreviation percentage
Bod-Kin LS1 60 
Intraper LS2 40
Verb-Ling LS3 20 
Spat-Vis LS4 10
Natur LS5 5 
Interper LS6 0 
Mus LS7 0 
Log-Math LS8 0
\end{filecontents*}
\usepackage{pgfplots,pgfplotstable}
\pgfplotsset{compat=1.16}
\definecolor{backgroundgray}{HTML}{EDEDED}
\definecolor{hashc}{HTML}{00A3E5}
\newcounter{mya}
\begin{document}
\begin{tikzpicture}
\pgfplotstableread[columns={Name,Abbreviation,percentage}]{tls.dat}\datatableA
\pgfplotstablesort[sort key={percentage}, sort cmp=int <]{\datatablesorted}{\datatableA}
\pgfplotstablegetrowsof{\datatablesorted} 
\pgfmathtruncatemacro{\RowsInTable}{\pgfplotsretval-1} 
\pgfmathtruncatemacro{\TotalRows}{\pgfplotsretval}
\setcounter{mya}{0} 
\foreach \k in {0,...,\RowsInTable}{
\pgfplotstablegetelem{\k}{percentage}\of{\datatablesorted}
\pgfmathtruncatemacro{\itest}{ifthenelse(\pgfplotsretval>0,1,0)}
\ifnum\itest=1
 \typeout{\k,\pgfplotsretval}
 \pgfplotstablegetelem{\k}{Abbreviation}\of{\datatablesorted}
 \typeout{\pgfplotsretval}
 \ifnum\number\value{mya}=0
 \xdef\LstAbbr{"\pgfplotsretval"}
 \else
 \xdef\LstAbbr{\LstAbbr,"\pgfplotsretval"}
 \fi
 \stepcounter{mya}
\fi}
\begin{axis}[xbar,hide axis,clip=false]
    \addplot [draw=none,fill=hashc,
     y filter/.expression={
        x<=0 ? nan : y
    }] table[y expr=\coordindex,x=percentage] {\datatablesorted};
\pgfplotsinvokeforeach{1,...,\number\value{mya}}{
    \node[left,gray] at (axis cs:0,#1-\number\value{mya}+\RowsInTable){\pgfmathparse{{\LstAbbr}[#1-1]}\pgfmathresult};}
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

A nontrivial test with different assignments:

\begin{filecontents*}{tls.dat} 
Name Abbreviation percentage
Bod-Kin LS1 60 
Intraper LS3 40
Verb-Ling LS4 20 
Spat-Vis LS2 10
Natur LS5 5 
Interper LS6 0 
Mus LS7 0 
Log-Math LS8 0
\end{filecontents*}

leads to

enter image description here

2
  • tls.dat is not sorted.. it will be added manually, and I need to have only rows that have values in chart.. not every single one.. this is why I am sorting data in Latex.. e.g. if I change LS8 to 70 and everything else stays the same, then I wil have empty bar plots.. ... – Almic7 Jun 1 '19 at 20:41
  • @Almic7 Yes, sorry. I updated my answer. – user121799 Jun 1 '19 at 21:28

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.