1

How can the PGF library fillbetween be used to fill the area marked "A" in this figure? Here is the preliminary code for the figure:

\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{arrows,intersections}
\begin{document}
\begin{tikzpicture}[
    thick,
    >=stealth'
  ]

  % Setup
% \draw [help lines] grid (8,5);
  \coordinate (O) at (0,0);

  % Axes
  \draw[name path=x-axis,->] (-0.3,0) -- (8,0) coordinate[label = {below:$\tau$}] (xmax);
  \draw[name path=y-axis,->] (0,-0.3) -- (0,5) coordinate[label = {right:$v(\tau)$}] (ymax);

  % Value function
  \draw [blue, name path=value] (.5,4.5) .. controls (2,1)  .. (7.5,.5);

  \path [name path=level] (0,1) -- (8,1);
  \path [name intersections={of=level and value}];
    \draw[thin,gray] (0,1) node[black,left] {$\sigma$} -- (intersection-1);
    \fill[red] (intersection-1) circle (1pt);
    \draw[thin,gray,name path=taubp] (intersection-1) -- ++(0,-1) node[black,below] {$\tau^*$};

  \path [name path=levelup] (0,1.5) -- (8,1.5);
  \path [name intersections={of=levelup and value}];
    \draw[thin,gray] (0,1.5) node[black,left] {$\sigma+\epsilon$} -- (intersection-1);
    \fill[red] (intersection-1) circle (1pt);
    \draw[thin,gray,name path=taubp] (intersection-1) -- ++(0,-1.5) node[black,below] {$\tau^k$};

  \draw (2.6,1.15) node {A}; % temporary marker

\end{tikzpicture}
\end{document}

enter image description here

  • That library is part of the pgfplots package, I don't know if it works outside of an axis environment. – Torbjørn T. May 27 '18 at 17:37
1

As I say in a comment, I'm not sure if the fillbetween library can be used here, but there are other options. Here is one option that uses \clip. Note I gave names to the intersections you found with by={..}.

enter image description here

\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{arrows,intersections,backgrounds} % added backgrounds
\begin{document}
\begin{tikzpicture}[
    thick,
    >=stealth'
  ]

  % Setup
% \draw [help lines] grid (8,5);
  \coordinate (O) at (0,0);

  % Axes
  \draw[name path=x-axis,->] (-0.3,0) -- (8,0) coordinate[label = {below:$\tau$}] (xmax);
  \draw[name path=y-axis,->] (0,-0.3) -- (0,5) coordinate[label = {right:$v(\tau)$}] (ymax);

  % Value function
  \draw [blue, name path=value] (.5,4.5) .. controls (2,1)  .. (7.5,.5);

  \path [name path=level] (0,1) -- (8,1);
  \path [name intersections={of=level and value,by={lev}}];
    \draw[thin,gray] (0,1) node[black,left] {$\sigma$} -- (lev);
    \fill[red] (lev) circle (1pt);
    \draw[thin,gray,name path=taubp] (lev) -- ++(0,-1) node[black,below] {$\tau^*$};

  \path [name path=levelup] (0,1.5) -- (8,1.5);
  \path [name intersections={of=levelup and value,by={levup}}];
    \draw[thin,gray] (0,1.5) node[black,left] {$\sigma+\epsilon$} -- (levup);
    \fill[red] (levup) circle (1pt);
    \draw[thin,gray,name path=taubp] (levup) -- ++(0,-1.5) node[black,below] {$\tau^k$};

  \draw (2.6,1.15) node {A}; % temporary marker

\begin{scope}[on background layer]
\clip (lev) rectangle (levup);
\fill [blue!20] (.5,4.5) .. controls (2,1)  .. (7.5,.5) |- (O) -- cycle;
\end{scope}
\end{tikzpicture}
\end{document}

pgfplots

For fun, here is one possible method for making a diagram like this with pgfplots and the fillbetween library.

enter image description here

\documentclass[border=10pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.11}
\usepgfplotslibrary{fillbetween}
\begin{document}
\begin{tikzpicture}[
  declare function={f(\x)=exp(-0.5*\x+1.5)+0.5;} % some random function that looked OK
]

% for convenience, save the two x-values we want red dots at in macros
\newcommand\XTickA{2.5}
\newcommand\XTickB{4}
\begin{axis}[
  axis lines=center,
  xmin=-0.3,xmax=8,
  ymin=-0.3,ymax=5,
  % xtick/ytick=data means that ticks are placed at the
  % data points belonging to the first \addplot   
  xtick=data,
  ytick=data,
  typeset ticklabels with strut, % improves vertical alignment
  xticklabels={$\tau^k$,$\tau^*$},
  yticklabels={$\sigma+\epsilon$,$\sigma$},
  xlabel=$\tau$,
  ylabel=$v(\tau)$,
  domain=0.5:7.5,
  smooth
]

% because we have xtick=data,ytick=data, we first plot
% something with samples at our two x-values
% xcomb makes horizontal lines from the y-axis to the point
\addplot [xcomb, gray, samples at={\XTickA,\XTickB}] {f(x)};

% path used for lower boundary of the filled area
% if you have a compat setting lower than 1.11, you need to use
% (axis cs:x,y) for this path instead of (x,y)
\path [name path=level] (\XTickB,{f(\XTickB)}) -- (0,{f(\XTickB)});

% plot the function
\addplot [name path=value] {f(x)};

% ycomb makes vertical lines from x-axis
% add the red dots as markers
\addplot [ycomb,
          mark=*,
          mark options={red,mark size=1pt},
          gray,
          samples at={\XTickA,\XTickB}] {f(x)};

% the filling
% use soft clip to limit the domain of the filling
% I had to use a value slightly higher than 4.0 to get the
% correct filling, possibly due to some roundoff error.
\addplot [blue!10] fill between[of=value and level,
                                soft clip={domain=2.5:4.01}
                               ];

\end{axis}


\end{tikzpicture}
\end{document}
  • Thanks for the solution! For the TikZ solution, the "value" path is specified twice — once to draw the curve, and once for the fill. Is there a way to reuse the path that was defined the first time? – Michael May 28 '18 at 3:40
  • @Michael I don't know. – Torbjørn T. May 28 '18 at 7:44

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.