Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I want to create a plot using a non-standard plot-style that I don't see in the pgfplots manual. It would be nice if I could take advantage of the \pgfplotstableread function and then somehow loop over the rows and columns of the table to create my custom plot with a tikz picture. I have been looking at the pgfplots and pgfplotstable manuals and I am having trouble seeing if there is a way to do this! Any help would be appreciated!

share|improve this question
1  
You might want to take a look at the question about Kiviat plots, there's a couple of ideas there that could help you. Azoun used pgfplotstable directly, I let pgfplots take care of handling the looping and only changed the way the points were positioned using mathematical expressions. If you let us know more exactly what you're trying to do, we might be able to help more. –  Jake Mar 8 '11 at 19:05

1 Answer 1

up vote 5 down vote accepted

Thanks to Jake's suggestion (and a more thorough read of the pgfplotstable manual) I found the \pgfplotstablegetelem command. This was exactly what I needed to make my plot. Here is an example of what I wanted my plot to look like on the following fake data

A B C D
0.2 0.3 0.6 0.3
0.3 0.8 0.9 0.4
0.4 0.6 0.7 0.2
0.5 0.7 0.95 0.8
0.1 0.2 0.3 0.4
0.3 0.5 0.4 0.6

I set up this table in pairs of rows. The even rows give the lower bound of a range in my plot and the odd rows give the upper bound in the range.

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepackage{ifthen}

\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}[scale=10,x=1cm,y=1cm]
\pgfplotstableread[header=true]{table4.dat}{\datawhead}
\pgfplotstableread[header=false]{table4.dat}{\data}
\pgfplotstablegetrowsof{\datawhead} %Determine no. of rows
\pgfmathsetmacro{\rows}{\pgfplotsretval}
\pgfplotstablegetcolsof{\data} % Determine no. of cols
\pgfmathsetmacro{\cols}{\pgfplotsretval}

\draw[->,ultra thick] (0,0)--(1,0); % axes
\draw[->,ultra thick] (0,0)--(0,1);

\pgfmathsetmacro{\r}{\rows-2} % do some math to separate the range plots and categories
\pgfmathsetmacro{\cats}{\rows/2}
\pgfmathsetmacro{\lines}{\cats*\cols}
\pgfmathsetmacro{\seps}{1/ \lines*0.8}
\pgfmathsetmacro{\bufs}{1-\lines*\seps}
\pgfmathsetmacro{\bufs}{\bufs/\cats}
\pgfmathsetmacro{\catlen}{(\seps*\cols+\bufs)/2}

\foreach \j in {0,2,...,\r}{ % category loop
    \foreach \i/\clr in {0/red,1/blue,2/green,3/blue!40!red}{ %subcategory loop
        \pgfmathsetmacro{\jp}{\j+1}
        \pgfmathsetmacro{\x}{\bufs + \j*\catlen+\i*\seps} % x coordinate
        \pgfplotstablegetelem{\j}{[index]\i}\of\datawhead
        \pgfmathsetmacro{\ya}{\pgfplotsretval} % y coord 1
        \pgfplotstablegetelem{\jp}{[index]\i}\of\datawhead
        \pgfmathsetmacro{\yb}{\pgfplotsretval} % y coord 2
        \pgfplotstablegetelem{0}{[index]\i}\of\data
        \draw[lightgray, thin](\x,0)--(\x,1);
        \node[rectangle,fill=\clr,inner sep=1.2pt,minimum width=6pt](bottom) at (\x,\ya){};
        \node[rectangle,fill=\clr,inner sep=1.2pt,minimum width=6pt](top) at (\x,\yb){};
        \draw[\clr,thick](bottom)--(top);
        \draw(\x,-0.01)--(\x,0.01)node[rotate=90,left=4pt]{\pgfplotsretval};

    }
    \pgfmathsetmacro{\jm}{\j/2}
    \node[anchor=west] at (\bufs+\j*\catlen,-0.1){Category \jm};
}

\end{tikzpicture}
\end{document}

The output is here. This is almost exactly what I wanted and I though the code is a bit messy, it allows me to change my data and generate an updated plot easily. One last thing though... I can't seem to be able to get my categories indices to be integers.

Thank you Jake and also thanks to the authors of pgfplotstable!

The final figure

share|improve this answer
1  
pgfmath has an int command that truncates the decimal part of a number. However, \pgfmathsetmacro will always save its result as a floating point number, so you will have to use the slightly more verbose \pgfmathparse{int(\j/2)}\let\jm=\pgfmathresult to get integer category numbers. –  Jake Mar 10 '11 at 9:18
    
@Jake - I think it will also be possible to use \pgfmathtruncatemacro as an alternative, to obtain an integer. –  sdaau May 28 at 22:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.