6

I get output files from a code and I want to display the output file with pgfplots. I want to create several different plots with the same files. Therefore, I read them in a macro with pgfplotstable.

I know that the first column contains the x-axis values in seconds. For the plots I want to change the x-axis unit to milliseconds for each and every plot. Currently, I am doing this by multiplying the x-axis value by a thousand for every addplot by x expr=\thisrowno{0}*1000. In my opinion this wastes memory and compile time.

Is it possible to scale the first column values already in the pgfplotstableread?

In this thread I found columns/0/.style={preproc/expr={##1*1000}} for pgfplotstabletypeset but I could not find a similar command to permanently modifiy the values inside \chartdata. I also had a look at write to macro for pgfplotstablesetbut could not make it work.

\documentclass{standalone}
\usepackage{filecontents}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepackage{pgfplotstable}

\begin{document}

\begin{filecontents}{chartdata.txt}
time               value_1            value_2            value_3
s                  some_unit          some_unit          some_unit
0.                 0.                 0.                 0.         
100.E-09            27.541E-06        580.194E-09         19.8912E-06 
200.E-09            55.082E-06          1.18929E-06       40.2063E-06 
350.E-09            96.3935E-06         2.15546E-06       70.5431E-06 
575.E-09           158.361E-06          3.67572E-06      116.044E-06  
87.4788E-06        24.0925E-03       634.302E-06         17.6932E-03 
652.755E-06        179.775E-03          4.74164E-03      131.941E-03  
750.568E-06        206.714E-03         12.7344E-03       152.076E-03  
760.034E-06        209.321E-03         20.4248E-03       154.317E-03  
760.941E-06        209.571E-03         20.4985E-03       154.679E-03  
\end{filecontents}

\pgfplotstableread[
  skip first n=6, % 2+4 for filecontents header
]{chartdata.txt}{\chartdata}

\begin{tikzpicture}

  \begin{axis}[
    cycle list name=color list,
  ]
    \addplot+[
      % currenty no options
    ] table [
      x expr=\thisrowno{0}*1000,
      y expr=\thisrowno{1},
    ]{\chartdata};
    \addlegendentry{Value 1}
    \addplot+[
      % currenty no options
    ] table [
      x expr=\thisrowno{0}*1000,
      y expr=\thisrowno{2},
    ]{\chartdata};
    \addlegendentry{Value 2}
    \addplot+[
      % currenty no options
    ] table [
      x expr=\thisrowno{0}*1000,
      y expr=\thisrowno{3},
    ]{\chartdata};
    \addlegendentry{Value 3}
  \end{axis}
\end{tikzpicture}

\end{document}

1 Answer 1

3

You can create a new column

\pgfplotstablecreatecol
  [create col/expr={\thisrowno{0}*1000}]
  {time in ms}% column name
  \chartdata

and use it with x=time in ms in the plots.

\documentclass{standalone}
\usepackage{filecontents}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepackage{pgfplotstable}

\begin{document}

\begin{filecontents}{chartdata.txt}
time               value_1            value_2            value_3
s                  some_unit          some_unit          some_unit
0.                 0.                 0.                 0.         
100.E-09            27.541E-06        580.194E-09         19.8912E-06 
200.E-09            55.082E-06          1.18929E-06       40.2063E-06 
350.E-09            96.3935E-06         2.15546E-06       70.5431E-06 
575.E-09           158.361E-06          3.67572E-06      116.044E-06  
87.4788E-06        24.0925E-03       634.302E-06         17.6932E-03 
652.755E-06        179.775E-03          4.74164E-03      131.941E-03  
750.568E-06        206.714E-03         12.7344E-03       152.076E-03  
760.034E-06        209.321E-03         20.4248E-03       154.317E-03  
760.941E-06        209.571E-03         20.4985E-03       154.679E-03  
\end{filecontents}

\pgfplotstableread[
  skip first n=6, % 2+4 for filecontents header
]{chartdata.txt}{\chartdata}

\pgfplotstablecreatecol
  [create col/expr={\thisrowno{0}*1000}]
  {time in ms}% column name
  \chartdata

\begin{tikzpicture}
  \begin{axis}[
    cycle list name=color list,
  ]
    \addplot+[
      % currenty no options
    ] table [
      x=time in ms,
      y index=1,
    ]{\chartdata};
    \addlegendentry{Value 1}
    \addplot+[
      % currenty no options
    ] table [
      x=time in ms,
      y index=2,
    ]{\chartdata};
    \addlegendentry{Value 2}
    \addplot+[
      % currenty no options
    ] table [
      x=time in ms,
      y index=3,
    ]{\chartdata};
    \addlegendentry{Value 3}
  \end{axis}
\end{tikzpicture}
\end{document}

enter image description here


Another possibility is modifying the first column

\documentclass{standalone}
\usepackage{filecontents}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepackage{pgfplotstable}

\begin{document}

\begin{filecontents}{chartdata.txt}
time               value_1            value_2            value_3
s                  some_unit          some_unit          some_unit
0.                 0.                 0.                 0.         
100.E-09            27.541E-06        580.194E-09         19.8912E-06 
200.E-09            55.082E-06          1.18929E-06       40.2063E-06 
350.E-09            96.3935E-06         2.15546E-06       70.5431E-06 
575.E-09           158.361E-06          3.67572E-06      116.044E-06  
87.4788E-06        24.0925E-03       634.302E-06         17.6932E-03 
652.755E-06        179.775E-03          4.74164E-03      131.941E-03  
750.568E-06        206.714E-03         12.7344E-03       152.076E-03  
760.034E-06        209.321E-03         20.4248E-03       154.317E-03  
760.941E-06        209.571E-03         20.4985E-03       154.679E-03  
\end{filecontents}

\pgfplotstableread[
  skip first n=6, % 2+4 for filecontents header
]{chartdata.txt}{\chartdata}


\pgfplotstablemodifyeachcolumnelement{[index]0}\of\chartdata\as\cell{%
  \pgfkeys{/pgf/fpu=true}%
  \pgfmathparse{1000*\cell}%
  \pgfkeys{/pgf/fpu=false}%
  \edef\cell{\pgfmathresult}%
}%

\begin{tikzpicture}
  \begin{axis}[
    cycle list name=color list,
  ]
    \addplot+[
      % currenty no options
    ] table [
      x index=0,
      y index=1,
    ]{\chartdata};
    \addlegendentry{Value 1}
    \addplot+[
      % currenty no options
    ] table [
      x index=0,
      y index=2,
    ]{\chartdata};
    \addlegendentry{Value 2}
    \addplot+[
      % currenty no options
    ] table [
      x index=0,
      y index=3,
    ]{\chartdata};
    \addlegendentry{Value 3}
  \end{axis}
\end{tikzpicture}
\end{document}

enter image description here


A third possibility is scaling only the xtick labels using

scaled x ticks=false,
xticklabel={%
  \pgfmathparse{\tick*1000}%
  $\pgfmathprintnumber[fixed,precision=1]{\pgfmathresult}$%
}

as options for the axis environment.

\documentclass{standalone}
\usepackage{filecontents}
\usepackage{xintexpr}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepackage{pgfplotstable}

\begin{document}

\begin{filecontents}{chartdata.txt}
time               value_1            value_2            value_3
s                  some_unit          some_unit          some_unit
0.                 0.                 0.                 0.         
100.E-09            27.541E-06        580.194E-09         19.8912E-06 
200.E-09            55.082E-06          1.18929E-06       40.2063E-06 
350.E-09            96.3935E-06         2.15546E-06       70.5431E-06 
575.E-09           158.361E-06          3.67572E-06      116.044E-06  
87.4788E-06        24.0925E-03       634.302E-06         17.6932E-03 
652.755E-06        179.775E-03          4.74164E-03      131.941E-03  
750.568E-06        206.714E-03         12.7344E-03       152.076E-03  
760.034E-06        209.321E-03         20.4248E-03       154.317E-03  
760.941E-06        209.571E-03         20.4985E-03       154.679E-03  
\end{filecontents}

\pgfplotstableread[
  skip first n=6, % 2+4 for filecontents header
]{chartdata.txt}{\chartdata}

\begin{tikzpicture}
  \begin{axis}[
    cycle list name=color list,
    scaled x ticks=false,
    xticklabel={%
      \pgfmathparse{\tick*1000}%
      $\pgfmathprintnumber[fixed,precision=1]{\pgfmathresult}$%
    }
  ]
    \addplot+[
      % currenty no options
    ] table [
      x index=0,
      y index=1,
    ]{\chartdata};
    \addlegendentry{Value 1}
    \addplot+[
      % currenty no options
    ] table [
      x index=0,
      y index=2,
    ]{\chartdata};
    \addlegendentry{Value 2}
    \addplot+[
      % currenty no options
    ] table [
      x index=0,
      y index=3,
    ]{\chartdata};
    \addlegendentry{Value 3}
  \end{axis}
\end{tikzpicture}
\end{document}

Edit by krtek:

For values larger >16383.9998, e.g. for the y-axis use fpu engine:

scaled y ticks=false,
yticklabel={%
  \pgfkeys{/pgf/fpu=true}%
  \pgfmathparse{\tick*1000}%
  \pgfkeys{/pgf/fpu=false}
  $\pgfmathprintnumber[
    fixed,
    precision=1,
  ]{\pgfmathresult}$%
}
4
  • Thank you @esdd this is of course a possibility. The computational effort will be significantly reduced. Anyway, is it not possible to scale the column during the command pgfplotstableread already to save additional memory? Commented Jun 6, 2016 at 13:56
  • @krtek See my updated answer. Commented Jun 6, 2016 at 20:29
  • @krtek If it is just a scale issue, change only the tick labels and the unit in the plot label Commented Jun 6, 2016 at 22:42
  • @esdd @percusse option three is of course very clever, thanks. The compilation time for my test figure is drastically reduced compared to the original post. I'll do that for the moment. However, since I also have to do some calculations between the columns like y expr=\thisrowno{0}/\thisrowno{3} I always to be really aware of the individual ticks. But I guess you have to put some effort into creating the charts anyway. Nonetheless, I think a possibility to scale a columns during pgfplotstableread would still be a nice addition. Commented Jun 7, 2016 at 12:22

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.