9

I'm trying to produce this:

https://i.stack.imgur.com/O6poO.png

But I can't get any further than this:

http://i.imgur.com/aZMtvTn.png?1

This is my code:

\documentclass{minimal}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usetikzlibrary{intersections}
\pgfmathdeclarefunction{normal}{2}{%
  \pgfmathparse{1/(#2*sqrt(2*pi))*exp(-((x-#1)^2)/(2*#2^2))}%
}
\makeatletter
\pgfmathdeclarefunction{erf}{1}{%
  \begingroup
    \pgfmathparse{#1 > 0 ? 1 : -1}%
    \edef\sign{\pgfmathresult}%
    \pgfmathparse{abs(#1)}%
    \edef\x{\pgfmathresult}%
    \pgfmathparse{1/(1+0.3275911*\x)}%
    \edef\t{\pgfmathresult}%
    \pgfmathparse{%
      1 - (((((1.061405429*\t -1.453152027)*\t) + 1.421413741)*\t 
      -0.284496736)*\t + 0.254829592)*\t*exp(-(\x*\x))}%
    \edef\y{\pgfmathresult}%
    \pgfmathparse{(\sign)*\y}%
    \pgfmath@smuggleone\pgfmathresult%
  \endgroup
}
\makeatother
\pgfmathdeclarefunction{skew}{3}{%
        \pgfmathparse{(exp(-((x-#1)^2)/(2*(#2)^2))*((erf((#3*(x-#1))/(sqrt(2)*#2)))+1))/(sqrt(2*pi)*#2)}%
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
      hide y axis,
      axis lines*=center, 
      axis on top,
      no markers, 
      domain=-1:24, 
      samples=100,
      xlabel=\empty, 
      ylabel=\empty,
      every axis x label/.style={at=(current axis.right of origin),anchor=west},
      every axis y label/.style={at=(current axis.above origin),anchor=south},
      height=5cm, width=12cm,
      xmin = -1, xmax=24,
      xtick=, ytick=\empty,
      enlargelimits=false, 
      clip=false
  ]
  \addplot [name path=normal,very thick,cyan!85!black!50] {normal(14,3.416969)};
  \addplot [name path=skew,very thick,red!85!black!50] {skew(1,4,10)};
  \addplot [draw=green!70!black!20,very thick,fill=green!15!white!15,domain=-2:24] {min(normal(14,3.41696),skew(1,4,10))} \closedcycle;
\draw [red, thick, name intersections={of={normal and skew}}] ({rel axis cs:0,0}-|intersection-1) -- ({rel axis cs:0,1}-|intersection-1);
\end{axis}
\end{tikzpicture}
\end{document}

I have checked Fill the area determined by two pgfplots graphs, but this example just uses a preset number for the domain of the area to be filled, while I intend to use the intersection (which I can't fill in under domain, e.g. domain:intersection-1:12 doesn't work so well).

1010011010
  • 6,357

2 Answers2

12

Using the fillbetween library that was introduced in PGFPlots 1.10:

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepgfplotslibrary{fillbetween}
\usetikzlibrary{intersections}
\pgfmathdeclarefunction{normal}{2}{%
  \pgfmathparse{1/(#2*sqrt(2*pi))*exp(-((x-#1)^2)/(2*#2^2))}%
}
\makeatletter
\pgfmathdeclarefunction{erf}{1}{%
  \begingroup
    \pgfmathparse{#1 > 0 ? 1 : -1}%
    \edef\sign{\pgfmathresult}%
    \pgfmathparse{abs(#1)}%
    \edef\x{\pgfmathresult}%
    \pgfmathparse{1/(1+0.3275911*\x)}%
    \edef\t{\pgfmathresult}%
    \pgfmathparse{%
      1 - (((((1.061405429*\t -1.453152027)*\t) + 1.421413741)*\t 
      -0.284496736)*\t + 0.254829592)*\t*exp(-(\x*\x))}%
    \edef\y{\pgfmathresult}%
    \pgfmathparse{(\sign)*\y}%
    \pgfmath@smuggleone\pgfmathresult%
  \endgroup
}
\makeatother
\pgfmathdeclarefunction{skew}{3}{%
        \pgfmathparse{(exp(-((x-#1)^2)/(2*(#2)^2))*((erf((#3*(x-#1))/(sqrt(2)*#2)))+1))/(sqrt(2*pi)*#2)}%
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
      hide y axis,
      axis lines*=center, 
      axis on top,
      no markers, 
      domain=-1:24, 
      samples=20,
      xlabel=\empty, 
      ylabel=\empty,
      every axis x label/.style={at=(current axis.right of origin),anchor=west},
      every axis y label/.style={at=(current axis.above origin),anchor=south},
      height=5cm, width=12cm,
      xmin = -1, xmax=24,
      xtick=, ytick=\empty,
      enlargelimits=false, 
      clip=false
  ]
  \addplot [name path=normal,very thick,cyan!85!black!50] {normal(14,3.416969)};
  \addplot [name path=skew,very thick,red!85!black!50] {skew(1,4,10)};
  \path [name path=lower, name intersections={of=skew and normal}, intersection segments={of=skew and normal,sequence=B1 -- A2}];

  \path[name path=axis]
(axis cs:\pgfkeysvalueof{/pgfplots/xmin},0) --
(axis cs:\pgfkeysvalueof{/pgfplots/xmax},0);
  \addplot [yellow] fill between [of=lower and axis, soft clip={(intersection-2) rectangle (axis cs:\pgfkeysvalueof{/pgfplots/xmax},0)}];
\end{axis}
\end{tikzpicture}
\end{document}
Jake
  • 232,450
  • This worked great! For a while... the answer seems to be very sensitive to the values I chose for the graphs (i.e. sometimes it will fill a rectangle towards the actual xmin coordinates or xmax coordinates (in this case (-1,0) or (24,0)) of the axis, instead of directly downward at the intersection, especially when the intersection is between the value of 6.8-7.8). I suspect the intersection sequence to be the culprit. Maybe there's a way to calculate the intersection count dynamically? As in, an intersection in a certain x-interval? – 1010011010 May 24 '14 at 10:13
  • I've asked a followup question at http://tex.stackexchange.com/questions/180127/stacking-plots-in-animation-using-fill-between-library-with-dynamic-calculation?lq=1. – 1010011010 May 24 '14 at 12:52
2

Just for fun. This answer had been prepared long time ago.

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-plot,pst-eucl,pst-grad}

% Define a new style
\newpsstyle{region}
{
    fillstyle=gradient,
    gradbegin=green,
    gradend=yellow,
    gradmidpoint=.5,
    gradangle=30,
}

% Set some keys globally
\psset
{
    algebraic,
    saveNodeCoors,
    NodeCoorPrefix=n,
    PointName=none,
    PointSymbol=none,
    plotpoints=150,
}

% Define a function to plot
\def\f{x^4-4*x^2+3}

\begin{document}

\begin{pspicture}(-2.5,-1)(2.5,4)
  % Determine intersection points
  \pstInterFF{\f}{0}{-2}{A}
  \pstInterFF{\f}{0}{2}{B}
  % Fill the bounded regions
  \pscustom[style=region]
    {\psplot{nAx}{nBx}{\f}\psline(!nBx 0)(!nAx 0)}
  % Plot the curve
  \psplot{-2}{2}{\f}
  % Draw the coordinate axes
  \psaxes[ticksize=-2pt 2pt,labelFontSize=\scriptscriptstyle]
    {->}(0,0)(-2.5,-1)(2.5,3.75)[$x$,-90][$y$,90]
  % Draw the intersection points
  \psdots[linecolor=red](A)(B)
  % Put a label
  \uput[45](*0 {\f}){\scriptsize$y=x^4-4x^2+3$}
\end{pspicture}

\end{document}

enter image description here