7

I use the following code in order to fill with color the area between a function and the x axis and it works properly.

\documentclass[a4paper,10pt]{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[scale=1.2]
\foreach \x in {1.000,1.001,...,4.500}   
\draw[purple!15!white] (\x,{0})--(\x, {0.5*cos(deg(0.5*pi*\x)+0.5*pi)+2});
\draw[very thick, ->] (-1,0) -- (6,0)node[pos=1,below]{$x$};
\draw[very thick, ->] (0,-1) -- (0,4)node[pos=1,left]{$y$};
\node[below left](o) at (0,0){$0$};
\draw[ultra thick,purple,smooth,domain=0.5:5,samples=257,]
plot (\x, {0.5*cos(deg(0.5*pi*\x)+0.5*pi)+2});
\end{tikzpicture}
\end{document}

enter image description here

How can I do the same, using a Bezier curve (e.g. \draw[ultra thick, purple,smooth] (0.5,1.5)..controls(2,-0.5) and (3.5,4.5)..(5,2.5);) instead of 0.5cos(deg(0.5pi*\x)+0.5*pi)+2 ?

1
  • 2
    Filling an area under a curve that way is already a last-resort solution. PGF/TikZ would already provide a \clipping solution for that. The PGFPlots package provides the fillbetween library and if that doesn't work we can always use spath3. Sep 16, 2023 at 19:38

3 Answers 3

9

Filling an area with roughly 3500 thin stripes is something I'd do as a last resort. Just without delving into PGFPlots' fillbetween library (see ) and the whole power of the spath3 library we can do this by using an appropriate \clip.

The current subpath start is a dynamic coordinate that references the start of the current subpath – thanks Caption Obvious – which is the point where the last move to operation landed. That's where cycle would bring us to.

However we don't want to cycle directly to that point but want enclose everything below it up to the y = 0.
The coordinate (0,0 -| current subpath start) is the base point of current subpath start.

Code

\documentclass[a4paper, 10pt]{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[
  scale=1.2,
  declare function={
    trig(\x)=.5*cos(deg(.5*pi*\x)+.5*pi)+2;
  }]
\fill[purple!15] plot[smooth, domain=1:4.5, samples=257] (\x, trig \x)
                 |- (0,0-|current subpath start) -- cycle;

\draw[very thick, ->] (-1,0) -- (6,0)node[below]{$x$};
\draw[very thick, ->] (0,-1) -- (0,4)node[left] {$y$};
\node[below left] {$0$};
\draw[ultra thick, purple, smooth, domain=0.5:5, samples=257]
  plot (\x, trig \x);
\end{tikzpicture}

\begin{tikzpicture}[
  scale=1.2,
  my curve/.style={
    insert path={(0.5,1.5)..controls(2,-0.5) and (3.5,4.5)..(5,2.5)}}
]
\begin{scope}
  \clip (1,0) rectangle (4.5, 4); % the y value of 4 needs to be carefully chosen
  \fill[purple!15, my curve] |- (0,0-|current subpath start) -- cycle;
\end{scope}
\draw[very thick, ->] (-1,0) -- (6,0) node[below]{$x$};
\draw[very thick, ->] (0,-1) -- (0,4) node[left] {$y$};
\node[below left] {$0$};
\draw[ultra thick, purple, my curve];
\end{tikzpicture}
\end{document}

Output

enter image description here

enter image description here

4
\documentclass[a4paper,10pt]{article}
\usepackage{tikz}
\begin{document}
    \begin{tikzpicture}[scale=1.2]
        \begin{scope}
            \clip (0.5,0) -- (0.5,1.5) ..controls (2,-0.5) and (3.5,4.5).. (5,2.5) |- cycle;
            \foreach \x in {1.000,1.001,...,4.500}   
                \draw[purple!15!white] (\x,{0}) -- ++(0,4);
        \end{scope}
        \draw[very thick, ->] (-1,0) -- (6,0)node[pos=1,below]{$x$};
        \draw[very thick, ->] (0,-1) -- (0,4)node[pos=1,left]{$y$};
        \node[below left] (o) at (0,0){$0$};
        \draw[ultra thick, purple, smooth]
            (0.5,1.5) ..controls (2,-0.5) and (3.5,4.5).. (5,2.5);
    \end{tikzpicture}
\end{document}

enter image description here

3

As plot is usable into a path, here is a simple solution:

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}[scale=1.2]
  \fill[purple!15!white](1,0) 
  -- plot[smooth,domain=1:4.5,samples=257](\x,{0.5*cos(deg(0.5*pi*\x)+0.5*pi)+2})
  -- (4.5,0) -- cycle;
  \draw[very thick, ->] (-1,0) -- (6,0)node[pos=1,below]{$x$};
  \draw[very thick, ->] (0,-1) -- (0,4)node[pos=1,left]{$y$};
  \node[below left](o) at (0,0){$0$};
  \draw[ultra thick,purple,smooth,domain=0.5:5,samples=257,]
  plot (\x, {0.5*cos(deg(0.5*pi*\x)+0.5*pi)+2});
\end{tikzpicture}
\end{document}

enter image description here

The same method used between two plots (using declare function for readability):

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}[scale=1.2]
  \tikzset{
    declare function={
      f1(\x) = 0.5*cos(deg(0.5*pi*\x)+0.5*pi)+1;
      f2(\x) = 0.5*cos(deg(2*pi*\x)+0.5*pi)+3;
    },
    samples=256,
  }
  \fill[purple!15!white] plot[smooth,domain=1:4.5](\x,{f1(\x)})
                     -- (4.5,0) -- (1,0) -- cycle;
  \fill[cyan!15!white] plot[smooth,domain=1.5:4](\x,{f1(\x)})
                   --  plot[smooth,domain=4:1.5](\x,{f2(\x)}) -- cycle;
  \draw[very thick, ->] (-1,0) -- (6,0)node[pos=1,below]{$x$};
  \draw[very thick, ->] (0,-1) -- (0,4)node[pos=1,left]{$y$};
  \node[below left](o) at (0,0){$0$};
  \draw[ultra thick,purple] plot[smooth,domain=0.5:5] (\x,{f1(\x)});
  \draw[ultra thick,cyan]   plot[smooth,domain=0.5:5] (\x,{f2(\x)});
\end{tikzpicture}
\end{document}

enter image description here

4
  • Nice. Out of curiosity, why samples=257?
    – Alan
    Sep 19, 2023 at 17:08
  • 1
    @Alan I just used the number of samples indicated in the question... Sep 19, 2023 at 22:04
  • @PaulGaborit Useful answer. Do you know if I there is a way to do something like that with two plot functions and the area between them?
    – GSpyros
    Sep 22, 2023 at 12:19
  • 1
    @GSpyros Done... Sep 22, 2023 at 22:35

You must log in to answer this question.

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