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. – Torbjørn T. May 22 '19 at 21:07
  • Thanks so much! That fixed the symmetry. For some reason though, adding [domain=2:5] removed the nice thick blue styling. – EthanAlvaree May 22 '19 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. – Torbjørn T. May 22 '19 at 21:19
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! – EthanAlvaree May 31 '19 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? – EthanAlvaree May 23 '19 at 16:53
  • I haven't tested Torbjørn T.'s answer but it looks like that might do what you want. – LarrySnyder610 May 23 '19 at 18:54

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.