# Drawing a sign-matrix for each factor of a function together with a range?

I want to draw the following diagram on Latex

Here is my MWE:

\documentclass[tikz]{standalone}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}

\draw [->, thick] (-5,0) -- (5,0)node[right] {$x$};
\foreach \x / \y  in %
{%
-2.5/{$1$},%
0/{$2$},%
2.5/{$3$}%
}
{\draw (\x,-.3) node[below] {\scriptsize \parbox{40pt}{\centering \y}} -- (\x,.3);}

\draw (-3.75,.5) node {\footnotesize \parbox{90pt}{\centering $f'(x)=4(x-1)(x-2)(x-3)$}};
\draw (-1.25,.5) node {\scriptsize \parbox{50pt}{\centering $---$ }};
\draw (1.25,.5) node {\scriptsize \parbox{50pt}{\centering $+++$ }};
\draw (3.75,.5) node {\scriptsize \parbox{50pt}{\centering $---$ }};

\draw (-2.5,.5) node {\scriptsize\parbox{15pt}{\centering $0$}};
\draw (0,.5) node {\scriptsize\parbox{15pt}{\centering $0$}};
\draw (2.5,.5) node {\scriptsize\parbox{15pt}{\centering $0$}};
%%%%%%%%%
\draw (-3.75,1) node {\scriptsize \parbox{50pt}{\centering $(x-3)$}};
\draw (-1.25,1) node {\scriptsize \parbox{50pt}{\centering $---$ }};
\draw (1.25,1) node {\scriptsize \parbox{50pt}{\centering $+++$ }};
\draw (3.75,1) node {\scriptsize \parbox{50pt}{\centering $---$ }};

%%%%%%%
\draw (-3.75,1.5) node {\footnotesize \parbox{90pt}{\centering $(x-2)$}};
\draw (-1.25,1.5) node {\scriptsize \parbox{50pt}{\centering $---$ }};
\draw (1.25,1.5) node {\scriptsize \parbox{50pt}{\centering $+++$ }};
\draw (3.75,1.5) node {\scriptsize \parbox{50pt}{\centering $---$ }};

%%%%%%%
\draw (-3.75,2) node {\footnotesize \parbox{90pt}{\centering $(x-1)$}};
\draw (-1.25,2) node {\scriptsize \parbox{50pt}{\centering $---$ }};
\draw (1.25,2) node {\scriptsize \parbox{50pt}{\centering $+++$ }};
\draw (3.75,2) node {\scriptsize \parbox{50pt}{\centering $---$ }};
\end{tikzpicture}
\end{document}

• Tabvar package does very easily tables of signs, clearer than any other pictures. have a look to tabavar examples on ctan.org. – pzorba75 Dec 18 '17 at 13:01
• @AlexRecuenco: I would rather have the "-" and the "+" filling the spaces in-between – marya Dec 18 '17 at 13:07

A stack/TABstack with the following salient points: stacks performed in math mode; 16pt baselineskip between rows; 1ex gap between columns; default column separator of TABstack changed from & to a simple space; I borrowed Herbert's \vector approach for the arrow.

\documentclass{article}
\usepackage{tabstackengine}
\stackMath
\begin{document}
$\setstackgap{L}{16pt} \Longunderstack[r]{x-1\\x-2\\x-3\\f'(x) = 4(x-1)(x-2)(x-3)} \setstackTAB{ } \setstacktabbedgap{1ex}\quad \tabbedLongunderstack{% - - - - 0 + + + + + + + + + + + + {}\\ - - - - - - - - 0 + + + + + + + + {}\\ - - - - - - - - - - - - 0 + + + + {}\\ - - - - 0 + + + 0 - - - 0 + + + + {}\\ \rlap{\raisebox{0.7ex}{\vector(1,0){200}}} % {} {} {} \stackunder{|}{\scriptstyle 1} % {} {} {} \stackunder{|}{\scriptstyle 2} % {} {} {} \stackunder{|}{\scriptstyle 3} % {} {} {} {} x}$
\end{document}


• I'm getting an error  {} {} {} {} x} while compiling with \documentclass{standalone}. What should I do? – marya Dec 19 '17 at 7:52
• @marya Change the $...$ math delimiters to $...$, or else use the [varwidth] option of standalone. – Steven B. Segletes Dec 19 '17 at 9:53
• I'm still getting the same error. Even with \documentclass{article} the error {} {} {} {} x} keeps showing. – marya Dec 19 '17 at 10:06
• @marya Make sure you have the latest package versions: tabstackengine: 2016/11/30 (V2.01), stackengine: 2016/10/04 v4.00, and listofitems: 2017/10/06 v1.5. – Steven B. Segletes Dec 19 '17 at 10:16
• Normally, your TeX installation would have a package manager for updating these things. But if you can't figure that out quickly, source files (.sty and/or .tex) can be found at ctan.org/pkg/tabstackengine, ctan.org/pkg/stackengine, and ctan.org/pkg/listofitems, respectively. If placed in the current directory, they will override the installed versions. – Steven B. Segletes Dec 19 '17 at 10:28

This is a non sophisticated solution with some TikZ

\documentclass{article}
\usepackage{tikz}

\newcommand\linenum{%
\begin{tikzpicture}[remember picture, overlay, >=stealth, shorten >= 1pt]
\draw[->, thick] (-5,0) to (6,0) node[right]{$x$};
\end{tikzpicture}%
}

\begin{document}

$\arraycolsep=8pt \begin{array}{rcccccc} (x-1) & 0 & + & + & + & + & + \\[1ex] (x-2) & - & - & 0 & + & + & + \\[1ex] (x-3) & - & - & - & - & 0 & + \\[1ex] f'(x)=4(x-1)(x-2)(x-3) & 0 & + & 0 & - & 0 & + \\[-1ex] \linenum & & & & & & \\[-1ex] &\rule{1pt}{2ex}& &\rule{1pt}{2ex}& &\rule{1pt}{2ex}& \\ & 1 & & 2 & & 3 & \end{array}$

\end{document}


UPDATE

Here is another style of variation table with matrix in TikZ, taking example of this answer

\documentclass[tikz,border=5mm]{standalone}
\usetikzlibrary{matrix}

\begin{document}

\begin{tikzpicture}
\matrix (m) [matrix of math nodes,
column sep = 0cm,
row sep = 0pt,
nodes = {align = center,
text width = 15mm,
text height = 3ex,
text depth = 1.5ex}
]
{
x-1     &   -   &   +   &   +   &   +\\
x-2     &   -   &   -   &   +   &   +\\
x-3     &   -   &   -   &   -   &   +\\
f'(x)   &   -   &   +   &   -   &   +\\
};
\foreach \i in {1, 2, 3, 4}
{
\draw (m-\i-1.north west) -- (m-\i-5.north east);
\draw (m-1-\i.north east) -- (m-4-\i.south east);
}
\draw   (m-4-1.south west) -- (m-4-5.south east);
%
\node[above] at (m-1-1.north east) {$-\infty$};
\node[above] at (m-1-2.north east) {$1$};
\node[above] at (m-1-3.north east) {$2$};
\node[above] at (m-1-4.north east) {$3$};
\node[above] at (m-1-5.north east) {$\infty$};

\tikzstyle{cero} = [above, inner sep=3mm]

\node[cero] at (m-2-2.north east) {$0$};
\node[cero] at (m-3-3.north east) {$0$};
\node[cero] at (m-4-4.north east) {$0$};

\end{tikzpicture}

\end{document}


A solution with simple LaTeX commands. Run with xelatex or lualatex or use another monospace font:

\documentclass{article}
\usepackage{fontspec}
\setmonofont{Anonymous Pro}[Scale=MatchUppercase]
\usepackage{array}
\begin{document}

\begin{tabular}{>{$}r<{$} >{\ttfamily}l}
x-1 & ----0++++++++++++\\
x-2 & --------0++++++++\\
x-3 & ------------0++++\\
f'(x)=4(x-1)(x-2)(x-3) & ----0+++0---0++++\\
& \rlap{~~~~|~~~|~~~|~~~~~x}%
\raisebox{0.5ex}{\vector(1,0){100}}\\
& ~~~~1~~~2~~~3
\end{tabular}

\end{document}


Why not letting TikZ do the math? [UPDATE: I added the ticks. f' is zero if and only if any of the above is zero. That's why it is very simple here. More generally, you'd have to compute the zeros of the products of all functions.]

\documentclass{article}
\usepackage{pgfplots}
\newcommand{\mysign}[1]{\pgfmathtruncatemacro\tmpsign{sign(#1)}
\ifnum\tmpsign<0
-
\else\ifnum\tmpsign>0
+
\else
0
\fi
\fi
}

\newcommand{\mytick}[1]{\pgfmathtruncatemacro\tmpsign{sign(#1)}
\ifnum\tmpsign<0
\relax
\else\ifnum\tmpsign>0
\relax
\else
$|$
\fi
\fi
}

\begin{document}

\begin{tikzpicture}[scale=1.5]
\draw [->, thick] (0,0) -- (5,0)node[right] {$x$};
\node[left] at (-0.5,4) {$x-1$};
\node[left] at (-0.5,3) {$x-2$};
\node[left] at (-0.5,2) {$x-3$};
\node[left] at (-0.5,1) {$f'(x)=4(x-1)(x-2)(x-3)$};
\foreach \i in {0,0.25,...,4}
{\node at (\i,4) {\mysign{\i-1}};
\node at (\i,3) {\mysign{\i-2}};
\node at (\i,2) {\mysign{\i-3}};
\node at (\i,1) {\mysign{4*(\i-1)*(\i-2)*(\i-3)}};
\pgfmathtruncatemacro\signum{sign((\i-1)*(\i-2)*(\i-3))}
\ifnum\signum=0
\node at (\i,0){$|$};
\node[below] at (\i,-0.2){$\i$};
\fi
}
\end{tikzpicture}

\end{document}


• Nice, could you show me how to I add the ticks on the axis aligned with each zero (In your case)? – marya Dec 19 '17 at 9:01

If you insist on using tikz, although Steven's answer is pretty clean, you could go with something similar to this, using a \matrix:

\documentclass{standalone}
\usepackage{tikz}

\usetikzlibrary{arrows.meta}
\usetikzlibrary{matrix}
\usetikzlibrary{calc}

\newcommand{\fillplus}{\xleaders\hbox{$+$}\hfill\kern0pt}
\newcommand{\fillminus}{\xleaders\hbox{$-$}\hfill\kern0pt}

\begin{document}
\begin{tikzpicture}[>={Stealth}]

\matrix (m) [
matrix of nodes,
nodes in empty cells,
row sep = 0.2cm,
column sep = 0.3ex,
column 1/.style={anchor = east},
column 2/.append style={text width = 2cm},
column 3/.append style={text width = 2cm},
column 4/.append style={text width = 2cm},
column 5/.append style={text width = 2cm}
]{
$x-1$ & \fillminus & \fillplus & \fillplus & \fillplus
\\
$x-2$ & \fillminus & \fillminus & \fillplus & \fillplus
\\
$x-3$ & \fillminus & \fillminus & \fillminus & \fillplus
\\[.5cm]
$f(x) = 4 (x-1)(x-2)(x-3)$ & \fillminus & \fillplus & \fillminus & \fillplus
\\
&&&&
\\
};
%Draw line
\draw[->] (m-5-2.west) -- (m-5-5.east);

%Ticks of line
\foreach \i [
remember= \i as \previ (initially 2),
evaluate=\i as \number using int(\i-2)] in {3,4,5}{
\draw ($(m-5-\previ)!0.5!(m-5-\i)$) -- +(0,3pt) -- +(0,-3pt)
node[below]{\number};
}

\end{tikzpicture}
\end{document}


The distance between the third and fourth rows is intentional. If you want to change that, you can simply replace the \\[.5cm] with \\

To get the zeros like in the original picture, you could add 3 extra row, and place the letter that you want there. But this is a good place to work from, and I think it looks somewhat clean.