3

I would like to plot the "u-shaped" or "bathtub" probability distribution using TikZ-PGF.

Using the u-quadratic's probability density function (pdf), I got the following results:

enter image description here

\documentclass[addpoints]{exam}
\usepackage{pgf,tikz}
\usepackage{pgfplots}
\usepgflibrary{shapes.geometric}
\usetikzlibrary{automata,arrows,positioning,calc,decorations.pathreplacing}
\usetikzlibrary{shapes}

%For plotting uniform distributions, see https://tex.stackexchange.com/questions/117954/probability-density-function-of-uniform-distribution
\makeatletter
\long\def\ifnodedefined#1#2#3{%
\@ifundefined{pgf@sh@ns@#1}{#3}{#2}%
}
\pgfplotsset{
discontinuous/.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 [densely dashed] (marker-|0,0) -- (0,0);
            \draw plot [mark=*,mark options={fill=white}] coordinates 
{(marker-|0,0)};
         \else
            \ifdim\pgf@y<0pt
                \tikzset{options/.style={mark=*,fill=white}}
                \draw [densely dashed] (marker-|0,0) -- (0,0);
                \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

%For plotting uniform distribution, see https://tex.stackexchange.com/questions/117954/probability-density-function-of-uniform-distribution
\pgfmathdeclarefunction{uniform}{3}{%
\pgfmathparse{(#1>=#2)*(#1<#3)*1/(#3-#2)}%
}

%For plotting normal distribution, see https://tex.stackexchange.com/questions/43610/plotting-bell-shaped-curve-in-tikz-pgf
\pgfmathdeclarefunction{gauss}{2}{%
\pgfmathparse{1/(#2*sqrt(2*pi))*exp(-((x-#1)^2)/(2*#2^2))}%
}

%For plotting u-shaped distribution, I wrote this myself!
\pgfmathdeclarefunction{bathtub}{2}{%
\pgfmathparse{12/(#2-#1)^3*(x-(#2+#1)/2)^2}%
}

\title{MWE}
\begin{document}
Uniform distribution:

\begin{tikzpicture}
\begin{axis}[height=6cm, 
axis lines=left,
ticks=none,
samples=11,
jump mark left,
ymin=0,ymax=1,
xmin=0, xmax=6,
every axis plot/.style={very thick},
discontinuous]
\addplot{uniform(x,2,4)};
\end{axis}
\end{tikzpicture}

U-shaped distribution:

\begin{tikzpicture}
\begin{axis}[height=6cm, 
axis lines=left,
ticks=none,
samples=100,
smooth,
ymin=0,ymax=2,
xmin=0, xmax=6]
\addplot[domain=2:5]{bathtub(2,5)};
\end{axis}
\end{tikzpicture}
\end{document}

The code compiles fine without any compilation errors, although when pasted in Overleaf, several of the lines of code are highlighted red for some reason.

I would like the style of the bottom graph to match the style of the top graph. In particular, I would like to have two closed circles at the peaks, two open circles at the base, vertical dotted lines connecting the circles at the discontinuities, and have the function be drawn at "zero" everywhere else, like the uniform example.

Specifically, I would like to adapt this answer to my situation, but I'm afraid I don't understand how the author's code works, so I don't know how to modify it.

Thank you in advance for your help!

3
  • Doesn't help to have a symmetric function like that if the sample domain is not symmetric about the minimum, by default it is is -5:5. Set e.g. domain=2:5. Commented May 22, 2019 at 21:07
  • Thanks so much! That fixed the symmetry. For some reason though, adding [domain=2:5] removed the nice thick blue styling. Commented May 22, 2019 at 21:17
  • You can add it to the axis options, or use +[domain=2:5]. With \addplot [<stuff>] ... the default style is replaced by <stuff>. With \addplot +[<stuff>] ..., <stuff> is appended to the default style. Commented May 22, 2019 at 21:19

2 Answers 2

2

You could do something like this, to parametrize things a bit.

\documentclass{article}

\usepackage{pgfplots}

%For plotting u-shaped distribution, I wrote this myself!
\pgfmathdeclarefunction{bathtub}{2}{%
\pgfmathparse{12/(#2-#1)^3*(x-(#2+#1)/2)^2}%
}

\begin{document}

\begin{tikzpicture}[
declare function={
  % define arguments to distribution, midpoint and 
  a=2;
  b=5;
  mid=(a+b)/2;
  span=1.5;
  },
  MyStyle/.style={blue, very thick}
]
% define macros that hold the limits for the bathtub
% didn't work with functions for domain settings, hence macros
\pgfmathsetmacro{\LeftPoint}{mid-span}
\pgfmathsetmacro{\RightPoint}{mid+span}
\begin{axis}[height=6cm,
axis lines=left,
ticks=none,
samples=100,
ymin=0,ymax=2,
xmin=0, xmax=6,
domain=\LeftPoint:\RightPoint,
]
% tub
\addplot [MyStyle] {bathtub(a,b)};
% vertical dashed lines
\addplot [MyStyle,
          mark=*,
          mark options={fill=blue,solid},
          dashed,
          ycomb,
          samples at={\LeftPoint,\RightPoint},
          ] {bathtub(a,b)};
% zero lines
\addplot [MyStyle, unbounded coords=jump] coordinates {(0,0)(\LeftPoint,0)(0,nan)(\RightPoint,0)(\RightPoint+0.5,0)};
% open circles
\addplot [MyStyle, mark=*, mark options={fill=white}, samples at={\LeftPoint,\RightPoint}] {0};

\end{axis}
\end{tikzpicture}
\end{document}
1
  • Thank you, Torbjørn! Commented May 31, 2019 at 21:59
1

This solution is very manual and inelegant, but I believe it works. Replace your second tikzpicture with:

\begin{tikzpicture}
\begin{axis}[height=6cm, 
axis lines=left,
ticks=none,
samples=100,
smooth,
ymin=0,ymax=2,
xmin=0, xmax=6]

% your original plot
\addplot[domain=2:5,very thick,blue]{bathtub(2,5)};

% function = 0
\addplot[very thick,blue] coordinates {(0,0) (2,0)};
\addplot[very thick,blue] coordinates {(5,0) (5.5,0)};

% vertical dashed lines
\addplot[densely dashed,very thick,blue] coordinates {(2,0) (2,1)};
\addplot[densely dashed,very thick,blue] coordinates {(5,0) (5,1)};

% open circles
\addplot[mark=*,blue,mark options={fill=white,very thick}] coordinates {(2,0)};
\addplot[mark=*,blue,mark options={fill=white,very thick}] coordinates {(5,0)};

% closed circles
\addplot[mark=*,blue,mark options={fill=blue}] coordinates {(2,1)};
\addplot[mark=*,blue,mark options={fill=blue}] coordinates {(5,1)};

\end{axis}
\end{tikzpicture}

enter image description here

2
  • Thank you very much - I gave you an upvote! I particularly appreciate the %comments that explain what the code is doing. As a follow-up, do you know how to make it so that, like in the uniform example, changing the parameters automatically changes the placement of the circles and dotted lines? Commented May 23, 2019 at 16:53
  • I haven't tested Torbjørn T.'s answer but it looks like that might do what you want. Commented May 23, 2019 at 18:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .