How to shade area from one point to other for hobby curves?

I am trying to construct a image similar to a book. I am almost done except a last thing. What I want is

and what I have is

All I need now is to shade the area from $a$ to $b$. I tried soft clip from pgf manual but it gives me an error. Any help is appreciated. Thanks in advance.

\documentclass{article}
\usepackage{pgf,tikz}
\usetikzlibrary{arrows}
\usetikzlibrary{hobby}
\begin{document}
\begin{tikzpicture}[use Hobby shortcut, line width =.5mm]
\coordinate (a) at (1.5,0);
\coordinate (b) at (1.5,2.8);
\coordinate (c) at (6.5,0);
\coordinate (d) at (6.5,2.8);

\draw[name path=a,dashed,thin] (a) -- (b);
\draw[name path=b,dashed,thin] (c) -- (d);
\node at (a) [below] {$a$};
\node at (c) [below] {$b$};
\draw[black,  thick, -latex] (-1, 0) -- (7, 0) node[right]{$x$};
\draw[black,  thick, -latex] (0, -1) -- (0, 4) node[above]{$y$};
%\usepgfplotslibrary{fillbetween}
\draw[name path=f] (1,1)..(2.2,2)..(3,3.4)..(4,3.8)..(5,3.4)..(6,2)..(7,1);
\draw[name path=g] (1,3.5)..(2.2,2)..(3,1.2)..(4,1)..(5,1.2)..(5.8,2)..(7,3.5);
\node at (1,1)   [below] {$f(x)$};
\node at (1,3.5) [above] {$g(x)$};
%\draw[latex-latex,line width =.3mm]  (4,1) -- (4,4) node [midway,fill=white] {$d_{\infty}(f,g)$};
\node at (4,4)   [above] {$x,f(x)$};
\node at (4,1)   [below] {$x,g(x)$};
\tikzfillbetween[ of=f and g, split,
]{top color=white,bottom color=gray!40}
\end{tikzpicture}

\end{document}


Note #1: your MWE is not complete: it requires the pgfplots package and the intersections TikZ library.

Note #2: to avoid warnings, you must add the fill between/on layer=main option.

First Version

You can use a clip operation to limit the effect of the \tikzfillbetween macro:

\documentclass{standalone}
\usepackage{tikz,pgfplots}
\usetikzlibrary{arrows,intersections,hobby,pgfplots.fillbetween}
\begin{document}
\begin{tikzpicture}[use Hobby shortcut, line width =.5mm,fill between/on layer=main]
\coordinate (a) at (1.5,0);
\coordinate (b) at (1.5,2.8);
\coordinate (c) at (6.5,0);
\coordinate (d) at (6.5,2.8);
\draw[name path=a,dashed,thin] (a) -- (b);
\draw[name path=b,dashed,thin] (c) -- (d);
\node at (a) [below] {$a$};
\node at (c) [below] {$b$};
\draw[black,  thick, -latex] (-1, 0) -- (7, 0) node[right]{$x$};
\draw[black,  thick, -latex] (0, -1) -- (0, 4) node[above]{$y$};
% \usepgfplotslibrary{fillbetween}
\draw[name path=f] (1,1)..(2.2,2)..(3,3.4)..(4,3.8)..(5,3.4)..(6,2)..(7,1);
\draw[name path=g] (1,3.5)..(2.2,2)..(3,1.2)..(4,1)..(5,1.2)..(5.8,2)..(7,3.5);
\node at (1,1)   [below] {$f(x)$};
\node at (1,3.5) [above] {$g(x)$};
% \draw[latex-latex,line width =.3mm]  (4,1) -- (4,4) node [midway,fill=white] {$d_{\infty}(f,g)$};
\node at (4,4)   [above] {$x,f(x)$};
\node at (4,1)   [below] {$x,g(x)$};
\begin{scope}
\clip (a) rectangle ([yshift=4cm]c);
\tikzfillbetween[ of=f and g, split]{top color=white,bottom color=gray!40}
\end{scope}
\end{tikzpicture}
\end{document}


Second Version

To get a better result, you must draw the curves after the \tikzfillbetween call:

\documentclass{standalone}
\usepackage{tikz,pgfplots}
\usetikzlibrary{arrows,intersections,hobby,pgfplots.fillbetween}
\begin{document}
\begin{tikzpicture}[use Hobby shortcut, line width =.5mm,fill between/on layer=main]
\coordinate (a) at (1.5,0);
\coordinate (b) at (1.5,2.8);
\coordinate (c) at (6.5,0);
\coordinate (d) at (6.5,2.8);
\draw[name path=a,dashed,thin] (a) -- (b);
\draw[name path=b,dashed,thin] (c) -- (d);
\node at (a) [below] {$a$};
\node at (c) [below] {$b$};
\path[black,  thick, -latex] (-1, 0) -- (7, 0) node[right]{$x$};
\draw[black,  thick, -latex] (0, -1) -- (0, 4) node[above]{$y$};
\path[name path=f] (1,1)..(2.2,2)..(3,3.4)..(4,3.8)..(5,3.4)..(6,2)..(7,1);
\path[name path=g] (1,3.5)..(2.2,2)..(3,1.2)..(4,1)..(5,1.2)..(5.8,2)..(7,3.5);
\node at (1,1)   [below] {$f(x)$};
\node at (1,3.5) [above] {$g(x)$};
\node at (4,4)   [above] {$x,f(x)$};
\node at (4,1)   [below] {$x,g(x)$};
\begin{scope}
\clip (a) rectangle ([yshift=4cm]c);
\tikzfillbetween[ of=f and g, split]{top color=white,bottom color=lime}
\end{scope}
\draw (1,1)..(2.2,2)..(3,3.4)..(4,3.8)..(5,3.4)..(6,2)..(7,1);
\draw (1,3.5)..(2.2,2)..(3,1.2)..(4,1)..(5,1.2)..(5.8,2)..(7,3.5);
\end{tikzpicture}
\end{document}


Third Version

You can use the pgfonlayer environment from backgrounds TikZ library to clip the fill between operation without repeat the curve operations (also, I take into account the marmot's comment about intersections and arrows libraries).

\documentclass{standalone}
\usepackage{tikz,pgfplots}
\usetikzlibrary{backgrounds,arrows.meta,hobby}
\usepgfplotslibrary{fillbetween}
\begin{document}
\begin{tikzpicture}[use Hobby shortcut,line width =.5mm,fill between/on layer=background]
\coordinate (a)  at (1.5,0);
\coordinate (a1) at (1.5,2.8);
\coordinate (b)  at (6.5,0);
\coordinate (b1) at (6.5,2.8);
\node at (a) [below] {$a$};
\node at (b) [below] {$b$};
\draw[black,thick,-Latex] (-.5, 0) -- (7, 0) node[right]{$x$};
\draw[black,thick,-Latex] (0, -.5) -- (0, 4) node[above]{$y$};
\draw[dashed,thin] (a) -- (a1);
\draw[dashed,thin] (b) -- (b1);
\draw[name path=f] (1,1)..(2.2,2)..(3,3.4)..(4,3.8)..(5,3.4)..(6,2)..(7,1);
\draw[name path=g] (1,3.5)..(2.2,2)..(3,1.2)..(4,1)..(5,1.2)..(5.8,2)..(7,3.5);
\node at (1,1)   [below] {$f(x)$};
\node at (1,3.5) [above] {$g(x)$};
\node at (4,4)   [above] {$x,f(x)$};
\node at (4,1)   [below] {$x,g(x)$};
\begin{pgfonlayer}{background}
\clip (a) rectangle ([yshift=4cm]b);
\tikzfillbetween[of=f and g,split]{top color=yellow,bottom color=red,middle color=white}
\end{pgfonlayer}
\end{tikzpicture}
\end{document}


• Sorry about MWE not being complete and Thanks for Note#2. I notice that by clipping the edges are thick and center part becomes thinner. – Kumarm Aug 1 at 0:07
• Thanks it worked, FYI the x axis is not showing however I can fix it. Once again Thank you very much. – Kumarm Aug 1 at 0:16
• It is actually better not to load the intersections library separately since the one coming with the pgfplots fillbetween library is slightly advanced. Also arrows is not needed here (and anyway superseded by arrows.meta), – user121799 Aug 1 at 2:13
• Another way to avoid computing the Hobby paths twice is to use the save Hobby path key to save the result for reuse. – Loop Space Aug 1 at 7:41

For completeness one more example :-). Using pgplots:

\documentclass[margin=3mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\usepgfplotslibrary{fillbetween}
\usetikzlibrary{intersections}

\begin{document}
\begin{tikzpicture}
\begin{axis}[axis lines = middle,
axis line style={-latex},
xmin=-0.3, xmax=8,
ymin=-0.3,
xlabel={$x$},
ylabel={$y$},
x label style={anchor=west},
y label style={anchor=south},
xtick=\empty, ytick=\empty,
]
\def\a1{1.5}
\def\b1{6.5}
coordinates {(1,1)   (2.2,2) (3,3.4) (4,3.8)
(5,3.4) (6,2)   (7,1)}   node[right] {$f(x)$};
coordinates {(1,3.5) (2.2,2) (3,1.2) (4,1)
(5,1.2) (5.8,2) (7,3.5)} node[right] {$g(x)$};
fill between [of=f and g,
soft clip={domain=\a1:\b1},
];
\path[name path=a]  (\a1,4) -- (\a1,0) node[below] (a1) {$a$};
\path[name path=b]  (\b1,4) -- (\b1,0) node[below] (b1) {$b$};
\draw[name intersections={of = a and g, by=a2}, dashed]
(a1) -- (a2);
\draw[name intersections={of = b and g, by=b2}, dashed]
(b1) -- (b2);
\path (a1) -- node[above=24mm] {$d_1(f,g)$} (b1);
\end{axis}
\end{tikzpicture}
\end{document}


• Thank you very much. I was wondering how this would be done using pgfplots. – Kumarm Aug 1 at 13:32