0

I want to filter some data for a plot, and so far the best thing I found is this here.

This is the relevant code from the mentioned question:

  \pgfplotsset{
    discard if not and smaller/.style n args={4}{
        x filter/.code={
            \edef\tempa{\thisrow{#1}}
            \edef\tempb{#2}
            \edef\tempc{\thisrow{#3}}
            \edef\tempd{#4}
            \ifnum\tempa=\tempb
                \ifnum\tempc<\tempd
                    \def\pgfmathresult{inf}
                \else
                \fi
            \else
                \def\pgfmathresult{inf}
            \fi
        }
    }
    }

    \begin{tikzpicture}
    \begin{axis}
    \addplot [ultra thick, 
              black, 
              discard if not and smaller={P}{0}{X}{5}] table [x=X, y=Y] {data.dat};
    \end{tikzpicture}

As far as I see, conditionals with \ifnum only work with integers. So I tried to replace it with dimension, as I need floats. And I want to check for inequality (i.e. the data should lie inside a certain range)

\pgfplotsset{
    discard if out of range/.style n args={3}{
        x filter/.code={
            \edef\tempa{\thisrow{#1}}
            \edef\tempb{#2}
            \edef\tempc{#3}
            \ifdim\tempa pt> \tempb pt
              \ifdim\tempa pt< \tempc pt
              \else
                \def\pgfmathresult{inf}
              \fi
            \else
              \def\pgfmathresult{inf}
            \fi
        }
    }
}

However, I always get an error: Missing number, treated as zero. at the line of the \addplot utilizing the new option. I think that it might have to do something with how Tex and pgfplots evaluate the expression, like \thisrow{#1} but I have no idea how to find this out...

Finally, a complete example:

\documentclass{standalone}

\usepackage{pgfplots,pgfplotstable,filecontents}

\begin{filecontents}{file.dat}
x y z
0 1 2
2 3 3.5
3 4 5
\end{filecontents}

\pgfplotsset{
    discard if out of range/.style n args={3}{
        x filter/.code={
            \edef\tempa{\thisrow{#1}}
            \edef\tempb{#2}
            \edef\tempc{#3}
            \ifdim\tempa pt> \tempb pt
              \ifdim\tempa pt< \tempc pt
              \else
                \def\pgfmathresult{inf}
              \fi
            \else
              \def\pgfmathresult{inf}
            \fi
        }
    }
}  

\begin{document}
\begin{tikzpicture}
\begin{axis}[unbounded coords=discard ,filter discard warning=false,]    
      \pgfplotstableread{file.dat}\datatable
            \addplot[scatter,point meta=explicit,] table [
                meta = z,
                discard if out of range={x}{0.5}{4},
                ]   from \datatable {};               
\end{axis}
\end{tikzpicture}
\end{document}
Stefan Pinnow
  • 29,535
crateane
  • 2,217

1 Answers1

1

If you just want to filter values in a closed range then you should use the key restrict x to domain=<min>:<max> as already mentioned in the comment to the question.

Here a real MWE using this feature from your provided code.

    \begin{filecontents}{file.dat}
        x y z
        0 1 2
        2 3 3.5
        3 4 5
    \end{filecontents}
\documentclass[border=2mm]{standalone}
\usepackage{pgfplots}
\begin{document}
    \begin{tikzpicture}
        \begin{axis}
                \pgfplotstableread{file.dat}\datatable
            % without restricting the domain
            \addplot+ [very thick] table {\datatable};
            % with restricting the domain
            \addplot table [
                restrict x to domain=0.5:4,
            ] {\datatable};
        \end{axis}
    \end{tikzpicture}
\end{document}

image showing the result of above code

Stefan Pinnow
  • 29,535