6

I'm trying to fill an area under a curve drew with pgfplots. I've tried the solution outlined in this answer:

\documentclass{article}
\usepackage{amsmath}
\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{pgfplots}

\colorlet{shadecolor}{gray!10}
\numberwithin{equation}{section}

\pgfplotsset{%
    compat=1.11,
    standard/.style={%
        clip=false,
        mark=none,
        smooth,
        axis x line*=bottom,
        axis y line=left,
        axis x line=middle,
        axis y line=middle,
        enlarge x limits=0.15,
        enlarge y limits=0.15,
        every axis x label/.style={at={(current axis.right of origin)},anchor=north west},
        every axis y label/.style={at={(current axis.above origin)},anchor=north east}
    }
}
\usepgfplotslibrary{fillbetween}

\begin{document}
\begin{figure}[!h]
    \centering
    \begin{tikzpicture}
        \newcommand\gaussian{1.0298076 * exp(-(x-2)^2 / 0.48)}
        \pgfplotsset{ticks=none};

        \begin{axis}[standard,every axis plot post/.append style={%
                domain=0:4,samples=200},
        xlabel={$x$},
        ylabel={$p(x)$},
        enlargelimits=upper]
            \addplot[name path=f,CornflowerBlue]{\gaussian};
            \path[name path=axis] (axis cs:0,0) -- (axis cs:1,0); %%%% The problem
            \addplot[
                thick,
                color=blue,
                fill=blue,
                fill opacity=0.05
            ]
            fill between[
                of=f and axis,
                soft clip={domain=1.6:2.4}
            ];
            \addplot[dashed] coordinates {(2.4,0) (2.4,0.737889)};
            \addplot[dashed] coordinates {(1.6,0) (1.6,0.737889)};
            \node at (axis cs:2.4,0.001) [below] {$\mu + \sigma$};
            \node at (axis cs:1.6,0.001) [below] {$\mu - \sigma$};
        \end{axis}
    \end{tikzpicture}
    \caption{Intervallo di confidenza}\label{fig:distib_norm}
\end{figure}
\end{document}

However, in the logs I see

Package pgf Warning: fill between skipped: the second input path is empty. on input line 55.

The offending line is therefore this one:

\path[name path=axis] (axis cs:0,0) -- (axis cs:1,0);

How can it be empty?
This is the result:
enter image description here.

  • Well, the path is not empty but to short. Try with (axis cs:0,0)--(axis cs:5,0). If you place x axis labels at (axis cs:1.6,0.001) and (axis cs:2.4,0.001), it's clear that axis path is to short to cut the gaussian path. – Ignasi Mar 6 '15 at 8:15
  • @Ignasi Aw thank you. I read somewhere that the values of axis cs had to be between 0 and 1. Now it works! – rubik Mar 6 '15 at 8:17
  • I also remember something similar, so we will have to look for it again ;-) – Ignasi Mar 6 '15 at 8:20
  • 4
    Actually rel axis cs runs from 0 to 1 where as axis cs takes the actual domain dimensions (here from 0 to 4). – user11232 Mar 6 '15 at 9:44
  • @HarishKumar Ahh that's how it is. Thank you for the clarification! – rubik Mar 6 '15 at 10:03
5

axis cs (axis coordinate system) is the coordinate system to be used inside of an axis. It's the default coordinate system, so it's not necessary to prefix coordinates with it.

Therefore, command

\path[name path=axis] (axis cs:0,0) -- (axis cs:1,0);

defines a path from coordinate (0,0) to coordinate (1,0). This path is too short to intersect with the Gaussian curve which is drawn between x=0 and x=4.

The easiest solution would be to use (remember, no need for axis cs prefix)

\path[name path=axis] (0,0) -- (5,0);

Perhaps you confused axis cs with rel axis cs (relative coordinate system) which uses the complete axis vectors as units, i.e.

\path[name path=axis] (rel axis cs:0,0) -- (rel axis cs:1,0);

defines axis as the horizontal line between the lower and upper points in axis range. This is what you probably wanted to write.

\documentclass{article}
\usepackage{amsmath}
\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{pgfplots}

\colorlet{shadecolor}{gray!10}
\numberwithin{equation}{section}

\pgfplotsset{%
    compat=1.11,
    standard/.style={%
        clip=false,
        mark=none,
        smooth,
        axis x line*=bottom,
        axis y line=left,
        axis x line=middle,
        axis y line=middle,
        enlarge x limits=0.15,
        enlarge y limits=0.15,
        every axis x label/.style={at={(current axis.right of origin)},anchor=north west},
        every axis y label/.style={at={(current axis.above origin)},anchor=north east}
    }
}
\usepgfplotslibrary{fillbetween}

\begin{document}
\begin{figure}[!h]
    \centering
    \begin{tikzpicture}
        \newcommand\gaussian{1.0298076 * exp(-(x-2)^2 / 0.48)}
        \pgfplotsset{ticks=none};

        \begin{axis}[standard,every axis plot post/.append style={%
                domain=0:4,samples=200},
        xlabel={$x$},
        ylabel={$p(x)$},
        enlargelimits=upper]
            \addplot[name path=f,CornflowerBlue]{\gaussian};
% Next two lines are valid. Select the one you prefer
%            \path[name path=axis] (0,0) -- (5,0);
            \path[name path=axis] (rel axis cs:0,0) -- (rel axis cs:1,0); %%%% The problem
            \addplot[
                thick,
                color=blue,
                fill=blue,
                fill opacity=0.05
            ]
            fill between[
                of=f and axis,
                soft clip={domain=1.6:2.4}
            ];
            \addplot[dashed] coordinates {(2.4,0) (2.4,0.737889)};
            \addplot[dashed] coordinates {(1.6,0) (1.6,0.737889)};
            \node at (2.4,0.001) [below] {$\mu + \sigma$};
            \node at (1.6,0.001) [below] {$\mu - \sigma$};
        \end{axis}
    \end{tikzpicture}
    \caption{Intervallo di confidenza}\label{fig:distib_norm}
\end{figure}
\end{document}

plot

| improve this answer | |

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.