0

I am trying to reproduce this figure:

enter image description here

For this, I have reached this part of my code:

enter image description here

I have some issues, because:

  • I don't know how to implement the two gray rectangles below the axis.
  • Once the rectangles implemented: how can I fill the area between those rectangles with the cyan pattern? Since in my code I have just constructed a Gaussian function and filled the area under it. Therefore: I don't think it would be possible to fill the "gap" area between rectangles in the same way.
  • Also (this is a bit facultative) but it would be nice for me to learn how to draw this "Camera" figure if possible.

   \documentclass{article}
    \usepackage{amsmath}
    \usepackage{accents} % for bar under character
    %%%%%% PGFPLOTS %%%%%%%%%%%%
    \usepackage{pgfplots}
    \pgfplotsset{compat=newest}
    
    \pgfmathdeclarefunction{gaussian}{2}
    {%
        \pgfmathparse{(1/(#1 * sqrt(2 * pi))) * exp((-1 / 2) * (((x - #2)/#1) ^ 2))}%
    }
    \pgfmathsetmacro{\mean}{7}
    \pgfmathsetmacro{\std}{0.3}

    \usepackage{enumitem}
    \usepackage{pgf, tikz, adjustbox}
    \usepgfplotslibrary{fillbetween}
    \usetikzlibrary{patterns, matrix, positioning}
    \usetikzlibrary{arrows.meta,
                    patterns.meta
                    }

    \begin{tikzpicture}
    \begin{axis}[
      no markers, domain=0:14, samples=200,
      axis lines*=left, xlabel=$x$, ylabel=$y$,
      every axis y label/.style={at=(current axis.above origin),anchor=south},
      every axis x label/.style={at=(current axis.right of origin),anchor=west},
      height=5cm, width=17cm,
      xtick={\mean,12.5}, ytick=\empty,
      enlargelimits=false, clip=false, axis on top,
      grid = major
      ]
    
      \addplot [fill=cyan!20, draw=none, domain=0:14] {gaussian(1.5+\std,\mean)} \closedcycle;
      \addplot [name path=haute,very thick,cyan!50!black] {gaussian(1.5+\std, \mean)+0.05};
      \addplot [name path=basse,very thick,cyan!50!black] {gaussian(1.5+\std, \mean)};
      \addplot [very thick,cyan!50!black] {gaussian(1.5+\std, \mean)+0.05}--(14,0); % ligne entre fin de la fonction et axe des abscisses
      
      \addplot fill between[
        of = haute and basse,
        soft clip={domain=0:14},
        every even segment/.style  = {pink,opacity=.2}
      ];
    
    \draw[very thick, cyan!50!black]  (0,0) -- (0,0.05011524462);
    \draw[dashed,red, stealth-stealth, very thick] (8,0) -- node[fill=cyan!20,scale=0.75] {$h(x,t)$} (8,0.189940);
    \draw[dashed,red, stealth-stealth, thick] (7,0.025) -- node[fill=cyan!20,scale=0.75] {$R(x,t)$} (12.5,0.025);
    \draw [yshift=-0.6cm, -stealth](7,-0.1) -- node [fill=white] {$Q(t)$} (7,0);
    \draw[black, stealth-, very thick] (9,0.13) -- node[right,below right,scale=0.75] {Elastic membrane} (12,0.25);
    \draw[black, stealth-, very thick] (6,0.03) -- node[pos = 0.8,below left,scale=0.75] {Silicon oil} (3,0.25);
    %\draw [yshift=-0.6cm, latex-latex](axis cs:4,0) -- node [fill=white] {$Q(t)$} (axis cs:5.96,0);
    \end{axis}
    
    \end{tikzpicture}

EDIT :

When I add these lines:

\draw[black, fill=cyan!20] (6.25,-0.1) -- (6.25,0) -- (7.75,0) -- (7.75,-0.1) -- (6.25,-0.1);
\draw[black, fill=gray!20] (0,-0.075) -- (0,0) -- (6.25,0) -- (6.25,-0.075) -- (0,-0.075);
\draw[black, fill=gray!20] (14,-0.075) -- (14,0) -- (7.75,0) -- (7.75,-0.075) -- (14,-0.075);

I end up with this configuration:

enter image description here

How can I avoid that filled zone to cover the arrow?

7
  • (rel axis cs: 0,0) will point to the lower left corner and (rel axis cs: 1,1) will point to the upper right corner, etc. You can use screen coordinates by adding cm, or move outside the axis environment. See [name=...] in the axis options. Jun 21, 2022 at 15:13
  • 1
    I would have gone another way, starting with [axis lines=none] , but with all the work you've done you might as well keep going. Jun 21, 2022 at 15:19
  • 1
    What you are asking is very basic compared to the rest of your figure(at least how it is currently implemented). How did you get the figure? Try this: \filldraw[very thick, fill=lightgray] (0,0) rectangle (6.5,-0.08); Jun 21, 2022 at 15:40
  • @hpekristiansen you are right : I have succeeded in drawing rectangles but my main concern was to "fill" the region between the 2 rectangles with the same color as the area under the curve. I don't know how to do it : because I want the fill to be totally "unified" with the "fill" of the curve.
    – Waxler
    Jun 21, 2022 at 15:52
  • @Kormylo Thank you for your replies : I have edited my question because I want to show you exactly what I want to avoid after filling the area between the 2 rectangles.
    – Waxler
    Jun 21, 2022 at 16:49

1 Answer 1

2

And this is why it is better to add normal TikZ commands outside the axis environment.

\documentclass{standalone}
 \usepackage{amsmath}
 \usepackage{accents} % for bar under character
 %%%%%% PGFPLOTS %%%%%%%%%%%%
 \usepackage{pgfplots}
 \pgfplotsset{compat=newest}

 \pgfmathdeclarefunction{gaussian}{2}
 {%
     \pgfmathparse{(1/(#1 * sqrt(2 * pi))) * exp((-1 / 2) * (((x - #2)/#1) ^ 2))}%
 }
 \pgfmathsetmacro{\mean}{7}
 \pgfmathsetmacro{\std}{0.3}

 \usepackage{enumitem}
 \usepackage{pgf, tikz, adjustbox}
 \usepgfplotslibrary{fillbetween}
 \usetikzlibrary{patterns, matrix, positioning}
 \usetikzlibrary{arrows.meta,
                 patterns.meta
                 }
\begin{document}
 \begin{tikzpicture}
\draw[black, fill=cyan!20] (242.85564pt,-0.04128pt) rectangle (195.85132pt,-35.86281pt);
 \begin{axis}[
   no markers, domain=0:14, samples=200,
   axis lines*=left, xlabel=$x$, ylabel=$y$,
   every axis y label/.style={at=(current axis.above origin),anchor=south},
   every axis x label/.style={at=(current axis.right of origin),anchor=west},
   height=5cm, width=17cm,
   xtick={\mean,12.5}, ytick=\empty,
   enlargelimits=false, clip=false, axis on top,
   grid = major
   ]

   \addplot [fill=cyan!20, draw=none, domain=0:14] {gaussian(1.5+\std,\mean)} \closedcycle;
   \addplot [name path=haute,very thick,cyan!50!black] {gaussian(1.5+\std, \mean)+0.05};
   \addplot [name path=basse,very thick,cyan!50!black] {gaussian(1.5+\std, \mean)};
   \addplot [very thick,cyan!50!black] {gaussian(1.5+\std, \mean)+0.05}--(14,0); % ligne entre fin de la fonction et axe des abscisses

   \addplot fill between[
     of = haute and basse,
     soft clip={domain=0:14},
     every even segment/.style  = {pink,opacity=.2}
   ];

 \draw[very thick, cyan!50!black]  (0,0) -- (0,0.05011524462);
 \draw[dashed,red, stealth-stealth, very thick] (8,0) -- node[fill=cyan!20,scale=0.75] {$h(x,t)$} (8,0.189940);
 \draw[dashed,red, stealth-stealth, thick] (7,0.025) -- node[fill=cyan!20,scale=0.75] {$R(x,t)$} (12.5,0.025);
 \draw [yshift=-0.6cm, -stealth](7,-0.1) -- node [fill=white] {$Q(t)$} (7,0);
 \draw[black, stealth-, very thick] (9,0.13) -- node[right,below right,scale=0.75] {Elastic membrane} (12,0.25);
 \draw[black, stealth-, very thick] (6,0.03) -- node[pos = 0.8,below left,scale=0.75] {Silicon oil} (3,0.25);
 %\draw [yshift=-0.6cm, latex-latex](axis cs:4,0) -- node [fill=white] {$Q(t)$} (axis cs:5.96,0);
%%%%% remove from final version
\coordinate (A) at (axis cs: 6.25,-0.1);
\coordinate (B) at (axis cs: 7.75,0);
%%%%%
\draw[black, fill=gray!20] (0,-0.075) rectangle (6.25,0);
\draw[black, fill=gray!20] (14,-0.075) rectangle (7.75,0);
 \end{axis}
%%%%% remove from final version
\path(A);
\pgfgetlastxy{\xx}{\yy}
\node[above] at (current bounding box.north) {(\xx,\yy)};
\path(B);
\pgfgetlastxy{\xx}{\yy}
\node[above] at (current bounding box.north) {(\xx,\yy)};
 \end{tikzpicture}
\end{document}

demo

3
  • @Kormylo Thank you for your reply. I have another question : for instance how is it possible to "hide" a specific segment of a rectangular filled path. I have tested the function "three sided" but didn't work. For example : if I draw : \draw[black, fill=cyan!20] (6.25,-0.1) -- (6.25,0) -- (7.75,0) -- (7.75,-0.1) -- (6.25,-0.1); I want to hide/erase the line between (6.25,0) -- (7.75,0) without deleting the filled option. Thank you
    – Waxler
    Jun 22, 2022 at 7:21
  • 1
    \draw[black] is short for \path[draw=black], just as \fill[cyan] is short for \path[fill=cyan]. In other words, both drawing and filling are optional. Jun 22, 2022 at 13:07
  • @Kormylo : Thank you a lot !!
    – Waxler
    Jun 22, 2022 at 13:41

You must log in to answer this question.

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