2

I have a data.csv that looks like (note that there's no header) 0.0, 0.8, 0.5 0.5, 0.4, 0.7 1.0, 1.0, 0.4 that I want to plot using pgfplots. I want the plot to rescale the values in the 2nd (index = 1) and 3rd (index = 2) columns by the value in the first row, so that the values become 0.0, 1.0, 1.0 0.5, 0.5, 1.4 1.0, 1.25, 0.8 on the plot. Currently, the way I do this is setting y expr = \thisrowno{1}/0.8 when plotting the 2nd column on the y axis. However, the csv file changes often and having to hard-code this is costly. I also don't have control over the csv generation, so rescaling at data-generation is not feasible. I could easily process this in some other language prior to plotting, but I'm interested to know whether this can be done within pgfplots, and potentially using an arbitrary row (1st and last are obviously the most valuable)

MWE:

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{filecontents}

\begin{filecontents}{data.csv}
0.0, 0.8, 0.5
0.5, 0.4, 0.7
1.0, 1.0, 0.4
\end{filecontents}

\begin{document}
\begin{figure}
\centering
\begin{tikzpicture}
\begin{axis}
\addplot table [
       x index = {0}, y index = {1},
       y expr  = \thisrowno{1}/0.8,
       col sep = comma,
      ] {data.csv};
\end{axis}
\end{tikzpicture}
\end{figure}
\end{document}
2

You could just read the values in advance and then use them. This code is based on this answer, that answer. These answers have also been used here, I think.

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{filecontents}

\begin{filecontents}{data.csv}
0.0, 0.8, 0.5
0.5, 0.4, 0.7
1.0, 1.0, 0.4
\end{filecontents}
\newcommand*{\ReadOutElement}[4]{%
    \pgfplotstablegetelem{#2}{[index]#3}\of{#1}%
    \let#4\pgfplotsretval
}
\newcommand{\Normalization}[2]{\ReadOutElement{\datatable}{0}{#1}{#2}}
\newcommand{\NormalizationFromLastRow}[2]{
\pgfplotstablegetrowsof{\datatable}
\pgfmathtruncatemacro{\rownumber}{\pgfplotsretval-1}
\ReadOutElement{\datatable}{\rownumber}{#1}{#2}}
\begin{document}
\pgfplotstableread[header=false,col sep=comma]{data.csv}\datatable
\Normalization{1}{\mynorm}
\NormalizationFromLastRow{1}{\mylastnorm}
\typeout{\mylastnorm}
\begin{figure}
\centering
\begin{tikzpicture}
\begin{axis}
\addplot table [
       x index = {0}, y index = {1},
       y expr  = \thisrowno{1}/\mynorm,
       col sep = comma,
      ] {data.csv};
\end{axis}
\end{tikzpicture}
\end{figure}
\end{document}
  • Is there an easy way to get the last row? – Shffl Aug 9 '18 at 19:18
  • @Shffl I added a command that gets the normalization from the last row. It is sometimes confusing that the numbering starts at 0, at least for me... – user121799 Aug 9 '18 at 19:36

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.