3

I'm trying to create a line interval with some annotations, but found myself tinkering too much with nodes and positions. Is there any smarter way to do this kind of work? Also I'm very annoyed by the $f$ not being exactly under the mark, leading to a unbalanced arrow. I was not able to align [below] and [left] using different spacements.

Any hint is very welcome

\documentclass[tikz]{standalone}
\usetikzlibrary{arrows,shapes,svg.path}
\begin{document}
  \begin{tikzpicture}[x=2cm]
    \pgfmathsetmacro\N{int(5)};
    \pgfmathsetmacro\Nm{int(\N-1)}; 
    \pgfmathsetmacro\Nmm{int(\N-2)};

    % Draw the number line 
    \draw (0,0) -- (\Nmm,0);
    \draw [dotted] (\Nmm,0) -- (\Nm,0);
    \draw (\Nm,0) -- (\N,0);

    % Regular grid
    \foreach \i in {0,...,\Nmm} {
        \draw (\i,0.1) -- + (0,-0.2) node[below] {\small $x_\i$};
   }
    \draw(\Nm,0.1) -- + (0,-0.2) node[below] {\small $x_{N-1}$};
    \draw(\N,0.1) -- + (0,-0.2) node[below] {\small $x_{N}$};

    % Distance h
    \draw [|-] (0,.5) -- (0.35,.5) node[right] {$h$};
    \draw [-|] (.60,.5) -- (1,.5);

    % Staggered Grid 
    \foreach \i in {1,...,\Nmm} {
        \pgfmathsetmacro\j{int(2*\i-1)};
        \draw (\i-.5,0.1) -- +(0,-0.2) node[below] {\small $x_\frac{\j}{2}$};
   }
    \draw (\N-.5,0.1) -- + (0,-0.2) node[below]{\small $_{N-\frac{1}{2}}$};

    % Vector functions
    \foreach \i in {0,...,\N} { 
      \draw [red, fill=red,opacity=.3] (\i,0) circle (1mm) node[above=1cm,style={black,opacity=100}] {\small $\mathbf{v}$};
   }

    % Dv
    \foreach \i in {1,...,\Nmm} { 
        \pgfmathsetmacro\j{int(2*\i-1)};
        \draw (\i-.5,0) -- + (0,0) node[above=1cm] {\small $\mathbf{D}\mathbf{v}$};
        \draw [->,opacity=.3,thick] (\i-.9,1.25) -- (\i-.7,1.25);
        \draw [->,opacity=.3,thick] (\i-.1,1.25) -- (\i-.3,1.25);
    }
    \draw (\N-.5,0.0) -- + (0,-0.0) node[above=1cm] {\small $\mathbf{D}\mathbf{v}$};
    \draw [->,opacity=.3,thick] (\N-.9,1.25) -- (\N-.7,1.25);
    \draw [->,opacity=.3,thick] (\N-.1,1.25) -- (\N-.3,1.25);

    % Scalar functions
    \foreach \i in {1,...,\Nmm} { 
        \pgfmathsetmacro\j{int(2*\i-1)};
        \draw [blue,fill=blue,opacity=.2] (\i-.55,-.1) rectangle (\i-.45,.1) node[below=1cm, style={black,opacity=1}] {\small $f$};
        \draw [->,opacity=.3,thick] (\i-.55,-1.25) -- (\i-.80,-1.75);
        \draw [->,opacity=.3,thick] (\i-.35,-1.25) -- (\i-.20,-1.75);
    }
    \draw [blue,fill=blue,opacity=.2] (\N-.55,-.1) rectangle (\N-.45,.1) node[below=1cm, style={black,opacity=1}] {\small $f$};
    \draw [->,opacity=.3,thick] (\N-.55,-1.25) -- (\N-.80,-1.75);
    \draw [->,opacity=.3,thick] (\N-.35,-1.25) -- (\N-.20,-1.75);
    \draw [blue,fill=blue,opacity=.2] (-.05,-.1) rectangle (.05,.1) node[below=1cm, style={black,opacity=1}] {\small $f$};
    \draw [->,opacity=.3,thick] (0.01,-1.45) -- (.01,-1.75);
    \draw [blue,fill=blue,opacity=.2] (\N-.05,-.1) rectangle (\N+.05,.1) node[below=1cm, style={black,opacity=1}] {\small $f$};
    \draw [->,opacity=.3,thick] (\N,-1.45) -- (\N,-1.75);

    % Gf
    \foreach \i in {0,...,\N} { 
      \draw (\i,0) -- +(0,0) node[below=1.7cm] {\small $\mathbf{G}f$};
   }
\end{tikzpicture}
\end{document}
Lin
  • 1,191
  • your mwe has error. interchange order of the last two code lines! also interchange the secon and the third code lines! – Zarko Sep 09 '18 at 03:21
  • sorry for that. now is fully functional. – Lin Sep 09 '18 at 03:30
  • You are placing the nodes below a rectangle, not the center of that rectangle. –  Sep 09 '18 at 04:02

1 Answers1

3

Three basic things:

  1. You can draw paths between nodes, there is no need to use explicit coordinates.
  2. You can do more fancy foreach loops like \foreach \i in {0,...,\Nmm,\N,\Nm}, there is no need to do the \N and \Nm separately.
  3. If you place a node below after some path, it will be placed at the last point of that path. However, you want to place them below the centers of the squares. A rather quick fix is to use midway here.

This leads to a somewhat cleaner code.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{arrows,shapes,svg.path}
\begin{document}
  \begin{tikzpicture}[x=2cm]
    \pgfmathsetmacro\N{int(5)};
    \pgfmathsetmacro\Nm{int(\N-1)}; 
    \pgfmathsetmacro\Nmm{int(\N-2)};

    % Draw the number line 
    \draw (0,0) -- (\Nmm,0);
    \draw [dotted] (\Nmm,0) -- (\Nm,0);
    \draw (\Nm,0) -- (\N,0);

    % Regular grid
    \foreach \i in {0,...,\Nmm,\N,\Nm} {
        \draw (\i,0.1) -- + (0,-0.2) node[below,font=\small] {$x_\i$};
   }

    % Distance h
    \draw [|-|] (0,.5) -- (1,.5) node[midway,fill=white] {$h$};

    % Staggered Grid 
    \foreach \i in {1,...,\Nmm} {
        \pgfmathsetmacro\j{int(2*\i-1)};
        \draw (\i-.5,0.1) -- +(0,-0.2) node[below,font=\small] {$x_\frac{\j}{2}$};
   }
    \draw (\N-.5,0.1) -- + (0,-0.2) node[below,font=\small]{$_{N-\frac{1}{2}}$};

    % Vector functions
    \foreach \i in {0,...,\N} { 
      \draw [red, fill=red,opacity=.3] (\i,0) circle (1mm) 
      node[above=1cm,style={black,opacity=100},font=\small] (v\i) {$\mathbf{v}$};
   }

    % Dv
    \foreach \i [evaluate=\i as \j using {int(\i-1)}] in {1,...,\Nmm} { 
        \draw (\i-.5,0)  node[above=1cm,font=\small]  (D\i)
        {$\mathbf{D}\mathbf{v}$};
        \draw[->] (D\i) -- (D\i -| v\i.west);
        \draw[->] (D\i) -- (D\i -| v\j.east);
    }
    \draw (\N-.5,0.0) -- + (0,-0.0) node[above=1cm,font=\small] {$\mathbf{D}\mathbf{v}$};
    \draw [->,opacity=.3,thick] (\N-.9,1.25) -- (\N-.7,1.25);
    \draw [->,opacity=.3,thick] (\N-.1,1.25) -- (\N-.3,1.25);
    % Gf moved uo
    \foreach \i in {0,...,\N} { 
      \draw (\i,0) node[below=1.7cm,font=\small] (Gf\i) {$\mathbf{G}f$};
     }

    % Scalar functions
    \foreach \i [evaluate=\i as \j using {int(\i-1)}] in {1,...,\Nmm,\N} { 
        \draw [blue,fill=blue,opacity=.2] (\i-.55,-.1) rectangle (\i-.45,.1)
        node[midway,below=0.9cm, style={black,opacity=1},font=\small] (f\i) {$f$};
        % added midway and gave the nodes names
         \draw [->,opacity=.3,thick] (f\i) -- (Gf\i);
         \ifnum\i>0
         \draw [->,opacity=.3,thick] (f\i) -- (Gf\j);
         \fi
    }
     \draw [blue,fill=blue,opacity=.2] (-.05,-.1) rectangle (.05,.1) 
    node[midway,below=0.9cm, style={black,opacity=1},font=\small] (f0) {$f$};
    \draw [->,opacity=.3,thick] (f0) -- (Gf0);
     \draw [blue,fill=blue,opacity=.2] (\N-.05,-.1) rectangle (\N+.05,.1) 
    node[midway,below=0.9cm, style={black,opacity=1},font=\small] (fN) {$f$};
    \draw [->,opacity=.3,thick] (fN) -- (Gf\N);
\end{tikzpicture}
\end{document}

enter image description here