6

I'm using some code I found here which I modified a bit to draw cumulative distribution functions for discrete random variables.

The first plot works out great, but all subsequent plots have a point which mysteriously appears at the top left, even if the code that generates the next plot is identical. I'd like to understand exactly why.

Here's a minimal example:

\documentclass{article}

\usepackage{pgfplots, pgfplotstable}
\usepackage{tikz}

\makeatletter
\long\def\ifnodedefined#1#2#3{%
    \@ifundefined{pgf@sh@ns@#1}{#3}{#2}%
}

\pgfplotsset{
    cdf/.style={
    scatter,
    scatter/@pre marker code/.code={
            \ifnodedefined{marker}{
            \pgfpointdiff{\pgfpointanchor{marker}{center}}%
             {\pgfpoint{0}{0}}%
             \ifdim\pgf@y>0pt
                \tikzset{options/.style={mark=*}}
                \draw plot [mark=*,mark options={fill=white}] coordinates {(marker-|0,0)};
             \else
                \ifdim\pgf@y<0pt
                    \tikzset{options/.style={mark=*,fill=white}}
                    \draw plot [mark=*] coordinates {(marker-|0,0)};
                \else
                    \tikzset{options/.style={mark=none}}
                \fi
             \fi
        }
                {
            \tikzset{options/.style={mark=none}}        
        }
        \coordinate (marker) at (0,0);
        \begin{scope}[options]
    },
    scatter/@post marker code/.code={\end{scope}}
    }
}

\begin{document}

\begin{center}
\begin{tikzpicture}[scale = 0.7]
\begin{axis}[
    clip=false,
    jump mark left,
    ymin=0,ymax=1,
    xmin=-3, xmax=6,
    every axis plot/.style={very thick},
    cdf,
    table/create on use/cumulative distribution/.style={
        create col/expr={\pgfmathaccuma + \thisrow{f(x)}}   
    }
]
\addplot [blue] table [y=cumulative distribution]{
x f(x)
-3 0
-2 1/6
0 1/6
2 1/3
4 1/6
5 1/6
6 0
};
\end{axis}
\end{tikzpicture}
\end{center}

\begin{center}
\begin{tikzpicture}[scale = 0.7]
\begin{axis}[
    clip=false,
    jump mark left,
    ymin=0,ymax=1,
    xmin=-3, xmax=6,
    every axis plot/.style={very thick},
    cdf,
    table/create on use/cumulative distribution/.style={
        create col/expr={\pgfmathaccuma + \thisrow{f(x)}}   
    }
]
\addplot [blue] table [y=cumulative distribution]{
x f(x)
-3 0
-2 1/6
0 1/6
2 1/3
4 1/6
5 1/6
6 0
};
\end{axis}
\end{tikzpicture}
\end{center}

\end{document}

And the resulting output. You can see the mystery point added at the top-left of the second plot.

enter image description here

1 Answers1

3

I don't fully understand what the code is doing, bu the fix is to undefine the marker node. For that we can use the code from Is there a way to forget node names between TikZ pictures? and invoke:

\aeundefinenode{marker}%

before the next tikzpicture. As per Paul Gaborit's suggestion, to be more tikz-like, we can invoke this with a cdf init style to each \addplot:

cdf init/.code={\aeundefinenode{marker}}

enter image description here

Notes:

Code:

\documentclass{article}

\usepackage{pgfplots, pgfplotstable} \usepackage{tikz}

\makeatletter \long\def\ifnodedefined#1#2#3{% @ifundefined{pgf@sh@ns@#1}{#3}{#2}% } %% https://tex.stackexchange.com/questions/178778/is-there-a-way-to-forget-node-names-between-tikz-pictures (simplified version) \def\aeundefinenode#1{%% \ifnodedefined{#1}{\global\expandafter\let\csname pgf@sh@ns@#1\endcsname\relax}{}% }

\pgfplotsset{ cdf init/.code={\aeundefinenode{marker}}, cdf/.style={ scatter, scatter/@pre marker code/.code={ \ifnodedefined{marker}{ \pgfpointdiff{\pgfpointanchor{marker}{center}}% {\pgfpoint{0}{0}}% \ifdim\pgf@y>0pt \tikzset{options/.style={mark=}} \draw plot [mark=,mark options={fill=white}] coordinates {(marker-|0,0)}; \else \ifdim\pgf@y<0pt \tikzset{options/.style={mark=,fill=white}} \draw plot [mark=] coordinates {(marker-|0,0)}; \else \tikzset{options/.style={mark=none}} \fi \fi } { \tikzset{options/.style={mark=none}}
} \coordinate (marker) at (0,0); \begin{scope}[options] }, scatter/@post marker code/.code={\end{scope}} } }

\makeatother

\begin{document}

\begin{tikzpicture}[scale = 0.7] \begin{axis}[ clip=false, jump mark left, ymin=0,ymax=1, xmin=-3, xmax=6, every axis plot/.style={very thick}, cdf, table/create on use/cumulative distribution/.style={ create col/expr={\pgfmathaccuma + \thisrow{f(x)}}
} ] \addplot [cdf init, blue] table [y=cumulative distribution]{% <---------- Added 'cdf init'. x f(x) -3 0 -2 1/6 0 1/6 2 1/3 4 1/6 5 1/6 6 0 }; \end{axis} \end{tikzpicture} \begin{tikzpicture}[scale = 0.7] \begin{axis}[ clip=false, jump mark left, ymin=0,ymax=1, xmin=-3, xmax=6, every axis plot/.style={very thick}, cdf, table/create on use/cumulative distribution/.style={ create col/expr={\pgfmathaccuma + \thisrow{f(x)}}
} ] \addplot [cdf init, red] table [y=cumulative distribution]{% <---------- Added 'cdf init'. x f(x) -3 0 -2 1/6 0 1/6 2 1/3 4 1/6 5 1/6 6 0 }; \end{axis} \end{tikzpicture}

\end{document}

Peter Grill
  • 223,288