1

How to add decimals in \pgfplotstableread?

The following code works without decimals...

\pgfplotstableread[col sep=comma]{
label,startyear,endyear
D, 2003, 2008
E, 2008, 2011
F, 2012, 2014
G, 2013, 2017
}\events

...but not with decimals (where I have also added precision=1)...

\pgfplotstableread[col sep=comma,precision=1]{
label,startyear,endyear
D, 2003.8, 2008.2
E, 2008.9, 2011.7
F, 2012.3, 2014.5
G, 2013.5, 2017.4
}\events

....in the following code:

\documentclass{article}
\usepackage{tikz, pgfplotstable}
\usetikzlibrary{arrows.meta}
\usepackage[utf8]{inputenc}

% read in table
\pgfplotstableread[col sep=comma]{
label,startyear,endyear
A, 2011, 2012
B, 2016, 2018
C, 2018, 2022
}\authors


\pgfplotstableread[col sep=comma,precision=1]{
label,startyear,endyear
D, 2003.8, 2008.2
E, 2008.9, 2011.7
F, 2012.3, 2014.5
G, 2013.5, 2017.4
}\events


% add color columns
\pgfplotstablecreatecol[create col/set={blue!30}]{color}{\authors}
\pgfplotstablecreatecol[create col/set={red!30}]{color}{\events}

% append events table to authors table
\pgfplotstablevertcat{\authors}{\events}
% sort by startyear
\pgfplotstablesort[sort key=startyear]\sortedtable\authors

\begin{document}
\noindent\begin{tikzpicture}[x=7mm]
\pgfmathsetmacro\yscale{0.3} % scaling for y-direction 
                             % -- effectively vertical distance between bars
\pgfmathsetmacro\barheight{0.25} % height of bars

\pgfplotstablegetrowsof{\sortedtable}
\pgfmathsetmacro{\M}{\pgfplotsretval-1}

\foreach [count=\i,evaluate=\i as \ylevel using \i*\yscale] \row in {0,...,\M}{
  % get entries from table row
  \pgfplotstablegetelem{\row}{[index]0}\of\sortedtable
  \let\txt\pgfplotsretval
  \pgfplotstablegetelem{\row}{[index]1}\of\sortedtable
  \let\xstart\pgfplotsretval
  \pgfplotstablegetelem{\row}{[index]2}\of\sortedtable
  \let\xend\pgfplotsretval
  \pgfplotstablegetelem{\row}{[index]3}\of\sortedtable
  \let\barcolor\pgfplotsretval
  \xdef\TheLastY{\ylevel}
  
  \ifnum \xend=-1
    % single day entry, draw circle
    \filldraw [draw=black!99!\barcolor,fill=\barcolor] (\xstart-2000,-\ylevel)
      circle[radius=\barheight/2.5*1cm]
      node[black,right=3pt,font=\scriptsize] {\txt};
  \else
    % interval, draw a rectangle
    \fill [\barcolor] (\xstart-2000,-\ylevel-\barheight/2) rectangle
                        (\xend-2000,-\ylevel+\barheight/2);
     % add text label right of the rectangle
    \node [right,font=\scriptsize] at (\xend-2000,-\ylevel) {\txt};
  \fi
}

\draw [Stealth-Stealth] (2003-2000,0) -- (2003-2000,-\TheLastY-\yscale)
                                      -- (2023-2000,-\TheLastY-\yscale);

% add ticks on x-axis
\foreach \year in {2003, 2004, ..., 2022}
  \draw (\year-2000,-\TheLastY-\yscale) ++(0,3pt)
     -- ++(0,-6pt) node[rotate=45,anchor=east] {\year};
\end{tikzpicture}
\end{document}
0

1 Answer 1

1

If you use decimals, you cannot use \ifnum anymore, because it does not accept decimals. There should actually be no need for precision=1.

An easy solution would be to use \ifdim instead. You only would need to convert the numbers you want to compare to dimensions then, for example by adding pt to them.

Another solution would be to first perform a calculation with PGF/TikZ that is sure to return only integers. So you could first define \pgfmathsetmacro{\xendsign}{sign(\xend)} – which returns -1 for any negative number, 1 for any positive number and 0 for zero – and then test with \ifnum\xendsign=-1. This test would be true for any negative number then, not only for -1. Or you could calculate something like \pgfmathsetmacro{\xendint}{int(\xend)} and use this for testing.

\pgfplotsset{compat=1.18} 
\usetikzlibrary{arrows.meta}

% read in table
\pgfplotstableread[col sep=comma]{
label, startyear, endyear
A, 2011, 2012
B, 2016, 2018
C, 2018, 2022
}\authors

\pgfplotstableread[col sep=comma]{
label, startyear, endyear
D, 2003.8, 2008.2
E, 2008.9, 2011.7
F, 2012.3, 2014.5
G, 2013.5, 2017.4
H, 2011.5, -1       % added to test functionality
}\events

% add color columns
\pgfplotstablecreatecol[create col/set={blue!30}]{color}{\authors}
\pgfplotstablecreatecol[create col/set={red!30}]{color}{\events}

% append events table to authors table
\pgfplotstablevertcat{\authors}{\events}
% sort by startyear
\pgfplotstablesort[sort key=startyear]\sortedtable\authors

\begin{document}
\noindent\begin{tikzpicture}[x=7mm]
\pgfmathsetmacro\yscale{0.3} % scaling for y-direction 
                             % -- effectively vertical distance between bars
\pgfmathsetmacro\barheight{0.25} % height of bars

\pgfplotstablegetrowsof{\sortedtable}
\pgfmathsetmacro{\M}{\pgfplotsretval-1}

\foreach [count=\i, evaluate=\i as \ylevel using \i*\yscale] \row in {0,...,\M} {
  % get entries from table row
  \pgfplotstablegetelem{\row}{[index]0}\of\sortedtable
  \let\txt\pgfplotsretval
  \pgfplotstablegetelem{\row}{[index]1}\of\sortedtable
  \let\xstart\pgfplotsretval
  \pgfplotstablegetelem{\row}{[index]2}\of\sortedtable
  \let\xend\pgfplotsretval
  \pgfplotstablegetelem{\row}{[index]3}\of\sortedtable
  \let\barcolor\pgfplotsretval
  \xdef\TheLastY{\ylevel}
  
  \ifdim\xend pt=-1pt
    % single day entry, draw circle
    \filldraw [draw=black!99!\barcolor, fill=\barcolor] (\xstart-2000,-\ylevel)
      circle[radius=\barheight/2.5*1cm]
      node[black, right=3pt, font=\scriptsize] {\txt};
  \else
    % interval, draw a rectangle
    \fill [\barcolor] (\xstart-2000,-\ylevel-\barheight/2) rectangle
                        (\xend-2000,-\ylevel+\barheight/2);
     % add text label right of the rectangle
    \node [right, font=\scriptsize] at (\xend-2000,-\ylevel) {\txt};
  \fi
}

\draw [Stealth-Stealth] (2003-2000,0) -- (2003-2000,-\TheLastY-\yscale)
                                      -- (2023-2000,-\TheLastY-\yscale);

% add ticks on x-axis
\foreach \year in {2003, 2004, ..., 2022}
  \draw (\year-2000,-\TheLastY-\yscale) ++(0,3pt)
     -- ++(0,-6pt) node[rotate=45,anchor=east] {\year};
\end{tikzpicture}
\end{document}

The output would be:

enter image description here

1
  • great!!! Thanks a lot @Jasper!
    – Ommo
    Commented Sep 23, 2022 at 13:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .