5

Though there is an upvoted answer - the question is NOT answered.


It turned out, that without smooth the resulting figure gets produced and looks alright, but the error remains. How to get rid of the error?


This is a direct follow up question of Jake's answer, which works perfectly for global maxima and minima.

enter image description here

(I changed his code a little to get a custom node description, and apply it to my case with pgfplotstable and groupplot)

But how about local maxima and minima? How to get the maximum of the second peak?


What I tried:

It seemend an easy solution to me to introduce a second plot (maybe invisible) and add a domain restriction:

\addplot[blue,mark max=A, restrict expr to domain = {x}{3000:500000}] table[x expr= \thisrowno{0}, y expr= \thisrowno{1} ] from \myTable;

However I got the following error:

Package PGF Math Error: Could not parse input '' as a floating point number, sorry. The unreadable part was near ''. (in 'x '). ...= {x}{3000:500000},mark max=A]table{sample.table};

and the following image:

enter image description here

So it looks alright, but how to get rid of the error?

Any solutions? Thank you!


Unfortunately the solution provided by salim bou does not work with pfgplotstable and the way I load data, which is a must.


Updated MWE with pgfplotstable

\documentclass{article}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{groupplots}

\makeatletter
\pgfplotsset{
    compat=1.12,
    /tikz/max node/.style={
        anchor=south,
    },
    /tikz/min node/.style={
        anchor=north,
        name=minimum
    },
    mark min/.style={
        point meta rel=per plot,
        visualization depends on={x \as \xvalue},
        scatter/@pre marker code/.code={%
            \ifx\pgfplotspointmeta\pgfplots@metamin
            \def\markopts{}%
            \coordinate (minimum);
            \node[name=#1] {};%
            \else
            \def\markopts{mark=none}
            \fi
            \expandafter\scope\expandafter[\markopts,every node near coord/.style=green]
        },%
        scatter/@post marker code/.code={%
            \endscope
        },
        scatter,
    },
    mark min/.default={below},
    mark max/.style={
        point meta rel=per plot,
        visualization depends on={x \as \xvalue},
        scatter/@pre marker code/.code={%
            \ifx\pgfplotspointmeta\pgfplots@metamax
            \def\markopts{}%
            \coordinate (maximum);
            \node[name=#1] {};%
            \else
            \def\markopts{mark=none}
            \fi
            \expandafter\scope\expandafter[\markopts]
        },%
        scatter/@post marker code/.code={%
            \endscope
        },
        scatter
    },
    mark max/.default={above},
}
\makeatother

\usepackage{filecontents}
\begin{filecontents*}{sample.table}
    x y
    1 0.2
    10 0.1
    200 0.4
    3000 -0.3
    40000 0.3
    500000 -0.2
\end{filecontents*}


\pgfplotsset{
    discard if/.style n args={3}{
        x filter/.code={
            \edef\tempa{\thisrowno{#1}}
            \edef\tempb{#2}
            \edef\tempc{#3}
            \ifnum\tempa>\tempb
            \ifnum\tempa<\tempc
            \else
            \def\pgfmathresult{inf}
            \fi
            \else
            \def\pgfmathresult{inf}
            \fi
        }
    }
}


\begin{document}
    
    \begin{figure}
        \begin{tikzpicture}
        
        \pgfplotstableread[skip first n=1]{sample.table}\myTable
        
        \begin{groupplot}[
        group style={group name=group,
            group size=1 by 2,
            x descriptions at=edge bottom,
            y descriptions at=edge left,
            vertical sep=0.5cm,
        }]
        
        \nextgroupplot[xmode=log,xlabel={X},ylabel={Y},]
        
        \addplot[blue,mark max=A] table[x expr= \thisrowno{0}, y expr= \thisrowno{1} ] from \myTable;
        \addplot[red,mark max=B, restrict expr to domain = {x}{3000:500000}] table[x expr= \thisrowno{0}, y expr= \thisrowno{1} ] from \myTable;
        \end{groupplot}
        
        \node[above] at (A) {Hello World!};
        \node[above] at (B) {Hello World!};
        
        \end{tikzpicture}
    \end{figure}
    
\end{document}

I assume the reason is the use of \thisrow in the discard if-style. However table[x index={0}, y index={1}] does not work neither.


Old MWE (works with salim bou's answer)

\documentclass{article}
\usepackage{pgfplots}

\makeatletter
\pgfplotsset{
    compat=1.12,
    /tikz/max node/.style={
        anchor=south,
    },
    /tikz/min node/.style={
        anchor=north,
        name=minimum
    },
    mark min/.style={
        point meta rel=per plot,
        visualization depends on={x \as \xvalue},
        scatter/@pre marker code/.code={%
            \ifx\pgfplotspointmeta\pgfplots@metamin
            \def\markopts{}%
            \coordinate (minimum);
            \node[name=#1] {};%
            \else
            \def\markopts{mark=none}
            \fi
            \expandafter\scope\expandafter[\markopts,every node near coord/.style=green]
        },%
        scatter/@post marker code/.code={%
            \endscope
        },
        scatter,
    },
    mark min/.default={below},
    mark max/.style={
        point meta rel=per plot,
        visualization depends on={x \as \xvalue},
        scatter/@pre marker code/.code={%
            \ifx\pgfplotspointmeta\pgfplots@metamax
            \def\markopts{}%
            \coordinate (maximum);
            \node[name=#1] {};%
            \else
            \def\markopts{mark=none}
            \fi
            \expandafter\scope\expandafter[\markopts]
        },%
        scatter/@post marker code/.code={%
            \endscope
        },
        scatter
    },
    mark max/.default={above},
}
\makeatother

\usepackage{filecontents}
\begin{filecontents*}{sample.table}
    x y
    1 0.2
    10 0.1
    20 0.4
    30 -0.3
    40 0.3
    50 -0.2
\end{filecontents*}

\begin{document}
    
    \begin{figure}
        \begin{tikzpicture}
        \begin{axis}[
        xlabel={X},
        ylabel={Y},
        xmax=50,
        xmin=0,
        ymax=.5,
        ymin=-.5,
        width=15cm,
        height=5cm,
        ]
        \addplot[blue,smooth,mark max=A]table{sample.table};
        % \addplot[blue,smooth, restrict expr to domain = {x}{30:45},mark max=A]table{sample.table};
        \end{axis}
        
        \node[above] at (A) {Hello World!};
        \end{tikzpicture}
        \caption{Caption}
    \end{figure}
    
\end{document}
6

Referencing how to read a specific portion of a data file in pgfplots, you can create a test like this

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

Which compare content for every row of the given column name with values defined in the #2 and #3 parameters, if the first value is trapped between the two other the value is \pgfmathresult otherwise the row value is set to infinity.


Code

\documentclass{article}
\usepackage{pgfplots}

\makeatletter
\pgfplotsset{
    compat=1.12,
    /tikz/max node/.style={
        anchor=south,
    },
    /tikz/min node/.style={
        anchor=north,
        name=minimum
    },
    mark min/.style={
        point meta rel=per plot,
        visualization depends on={x \as \xvalue},
        scatter/@pre marker code/.code={%
            \ifx\pgfplotspointmeta\pgfplots@metamin
            \def\markopts{}%
            \coordinate (minimum);
            \node[name=#1] {};%
            \else
            \def\markopts{mark=none}
            \fi
            \expandafter\scope\expandafter[\markopts,every node near coord/.style=green]
        },%
        scatter/@post marker code/.code={%
            \endscope
        },
        scatter,
    },
    mark min/.default={below},
    mark max/.style={
        point meta rel=per plot,
        visualization depends on={x \as \xvalue},
        scatter/@pre marker code/.code={%
            \ifx\pgfplotspointmeta\pgfplots@metamax
            \def\markopts{}%
            \coordinate (maximum);
            \node[name=#1] {};%
            \else
            \def\markopts{mark=none}
            \fi
            \expandafter\scope\expandafter[\markopts]
        },%
        scatter/@post marker code/.code={%
            \endscope
        },
        scatter
    },
    mark max/.default={above},
}
\makeatother

\usepackage{filecontents}
\begin{filecontents*}{sample.table}
    x y
    1 0.2
    10 0.1
    20 0.4
    30 -0.3
    40 0.3
    50 -0.2
\end{filecontents*}


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


\begin{document}

    \begin{figure}
        \begin{tikzpicture}
        \begin{axis}[
        xlabel={X},
        ylabel={Y},
        xmax=50,
        xmin=0,
        ymax=.5,
        ymin=-.5,
        width=15cm,
        height=5cm,
        ]
        \addplot[blue,smooth,mark max=A]table{sample.table};
        \addplot[blue,smooth, discard if={x}{30}{45},mark max=B,red,draw=none]table{sample.table};
        \end{axis}

        \node[above] at (A) {Hello World!};
        \node[above] at (B) {Hello World!};
        \end{tikzpicture}
        \caption{Caption}
    \end{figure}

\end{document}

Result

enter image description here

5
  • aargh, always the same with these minimal examples, they are always to minimal. Your solution seems to be incompatible with my way of achieving the data (with pgfplotstable), probably because the discard if style also uses thisrow{#1}. Do you see a way around this? Oct 30 '15 at 9:26
  • Tray to update pgfplots the last version 1.12.1.
    – Salim Bou
    Oct 30 '15 at 9:40
  • I have the latest version. Oct 30 '15 at 9:41
  • Here the code with overleaf, no problem.
    – Salim Bou
    Oct 30 '15 at 9:54
  • Yes your code works as it is, but it doesn't if you use pgfplotstable. That's why I was asking if you could modify your solution, so it would work for my modified MWE? Thank you! Oct 30 '15 at 10:38

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.