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 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 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 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.
    – Wiss
    Jun 21 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.
    – Wiss
    Jun 21 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
    – Wiss
    Jun 22 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 at 13:07
  • @Kormylo : Thank you a lot !!
    – Wiss
    Jun 22 at 13:41

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.