1

I want to plot a piecewise constant function like that minimal example:

Hello, I want to plot a piecewise constant function like that minimal example:

\documentclass[tikz]{standalone}

\usepackage[utf8]{inputenx}
\usepackage[T1]{fontenc}

\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepackage{pgfplotstable}
\usepackage{xcolor}

% read variables from file
\usepackage{readarray}
\usepackage{filecontents}

\begin{document}

% Define the file in here
\begin{filecontents*}{val.ssv}
0.25 0.5 0.75
\end{filecontents*}

\begin{filecontents*}{xval.ssv}
0.2 0.4 0.6 0.8
\end{filecontents*}

% read values from the file
\readdef{val.ssv}{\valdef}
\readArrayij{\valdef}{val}{1}

\readdef{xval.ssv}{\xvaldef}
\readArrayij{\xvaldef}{xval}{1}

\begin{tikzpicture}[font=\large]

\begin{axis}[%
width=10cm,
height=7cm,
xmin=0,
xmax=1,
xmajorgrids,
ymin=0,
ymax=1,
]

%\foreach \i in {1,...,3}
%{
%   \addplot [solid, color=black] table[row sep=crcr]{%
%       \arrayij{xval}{\i}{1}   \arrayij{val}{\i}{1}\\
%       \arrayij{xval}{\i}{1}   \arrayij{val}{\i}{1}\\
%       \arrayij{xval}{\i+1}{1} \arrayij{val}{\i}{1}\\
%   };}


    \addplot [solid, color=black] table[row sep=crcr]{%
    \arrayij{xval}{1}{1}    \arrayij{val}{1}{1}\\
    \arrayij{xval}{1}{1}    \arrayij{val}{1}{1}\\
    \arrayij{xval}{2}{1}    \arrayij{val}{1}{1}\\
};
    \addplot [solid, color=black] table[row sep=crcr]{%
    \arrayij{xval}{2}{1}    \arrayij{val}{2}{1}\\
    \arrayij{xval}{2}{1}    \arrayij{val}{2}{1}\\
    \arrayij{xval}{3}{1}    \arrayij{val}{2}{1}\\
};
    \addplot [solid, color=black] table[row sep=crcr]{%
    \arrayij{xval}{3}{1}    \arrayij{val}{3}{1}\\
    \arrayij{xval}{3}{1}    \arrayij{val}{3}{1}\\
    \arrayij{xval}{4}{1}    \arrayij{val}{3}{1}\\
};


\end{axis}

\end{tikzpicture}

\end{document}

Instead of using the \addplot-command many times, I want to use a \foreach-loop like in the comment lines in the minimal example above. Unfortunately the call \arrayij{xval}{\i+1}{1} does not work. Does anybody know what I have to do to make it work?

Instead of using the \addplot-command many times, I want to use a \foreach-loop like in the comment lines in the minimal example above. Unfortunately the call \arrayij{xval}{\i+1}{1} does not work. Does anybody know what I have to do to make it work?

enter image description here

1
1

It is much easier using the syntax of readarray V2.0 (rather than the deprecated V1.x). Also, the key to solving the use of the arrays in your usage case is the introduction \the\numexpr for evaluating \i+1.

EDITED to heed the advice of comment by Schrödinger's cat, who knows pgfplots (I do not). Thanks for the suggestion.

\documentclass[tikz]{standalone}

\usepackage[utf8]{inputenx}
\usepackage[T1]{fontenc}

\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepackage{pgfplotstable}
\usepackage{xcolor}

% read variables from file
\usepackage{readarray}
\usepackage{filecontents}

\begin{document}

% Define the file in here
\begin{filecontents*}{val.ssv}
0.25 0.5 0.75 
\end{filecontents*}

\begin{filecontents*}{xval.ssv}
0.2 0.4 0.6 0.8 
\end{filecontents*}

% read values from the file
\readdef{val.ssv}\valdef
\readarray\valdef\val[-,1]

\readdef{xval.ssv}\xvaldef
\readarray\xvaldef\xval[-,1]

\begin{tikzpicture}[font=\large]

\begin{axis}[%
width=10cm,
height=7cm,
xmin=0,
xmax=1,
xmajorgrids,
ymin=0,
ymax=1,
]

\foreach \i in {1,...,3} 
{ 
  \edef\temp{\noexpand\addplot [solid, color=black] table[row sep=crcr]{% 
      \xval[\i,1]   \val[\i,1]\\ 
      \xval[\the\numexpr\i+1\relax,1] \val[\i,1]\\ };
}
\temp} 
\end{axis}
\end{tikzpicture}

\end{document}

Note: This code matches the output of the OP's MWE, even though his/her posted image does not.

enter image description here


I would also note that, since your data arrays are 1-D, you may, after reading the files, use the facilities of the embedded listofitems package to carry out the procedure (and here you don't even need the \numexpr.

\documentclass[tikz]{standalone}

\usepackage[utf8]{inputenx}
\usepackage[T1]{fontenc}

\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepackage{pgfplotstable}
\usepackage{xcolor}

% read variables from file
\usepackage{readarray}
\usepackage{filecontents}

\begin{document}

\setsepchar{ }
% Define the file in here
\begin{filecontents*}{val.ssv}
0.25 0.5 0.75 
\end{filecontents*}

\begin{filecontents*}{xval.ssv}
0.2 0.4 0.6 0.8 
\end{filecontents*}

% read values from the file
\readdef{val.ssv}\valdef
\readlist\val{\valdef}

\readdef{xval.ssv}\xvaldef
\readlist\xval{\xvaldef}

\begin{tikzpicture}[font=\large]

\begin{axis}[%
width=10cm,
height=7cm,
xmin=0,
xmax=1,
xmajorgrids,
ymin=0,
ymax=1,
]

\foreach \i in {1,...,3} 
{ 
  \edef\temp{\noexpand\addplot [solid, color=black] table[row sep=crcr]{% 
      \xval[\i]   \val[\i]\\ 
      \xval[\i+1] \val[\i]\\ };
}
\temp} 
\end{axis}
\end{tikzpicture}

\end{document}
4
  • 1
    You need \foreach \i in {1,...,3} { \edef\temp{\noexpand\addplot [solid, color=black] table[row sep=crcr]{% \xval[\i] \val[\i]\\ \xval[\i+1] \val[\i]\\ };}\temp} \end{axis} if you want to answer the question that way. You accidentally solve the problem by pasting the first row twice, but this is an accidental solution that won't work in general. See Chapter 8 Utilities and Basic Level Commands of the pgfplots manual for that. Personally I'd just use some variant of const plot to draw this with a single \addplot.
    – user194703
    Mar 4 '20 at 15:21
  • @Schrödinger'scat Thank you so much for the pgfplots tip. I could debug the readarray stuff, but had to take the OP's plot calls at face value. Mar 4 '20 at 15:30
  • You are welcome!
    – user194703
    Mar 4 '20 at 15:32
  • Thank you both a lot for the good tips!
    – S.B.
    Mar 4 '20 at 17:29

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.