Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

In this question tikz-matrix-as-a-replacement-for-tabular a nice solution was given to let the matrix in tikz behave like tabular.

In this solution cell/.style={rectangle} was used to draw lines around every cell. But usually, however, I'd rather not give my tables this "grid"-look.

Is there a way within the tikz matrix to draw horizontal lines between rows that essentially behave like \hline within tabular?

I know I could put a node in the first and final cell of a row and draw a line between them, but this is not really handy compared to a single command like \hline and not very automated either.

share|improve this question

3 Answers 3

up vote 10 down vote accepted

You can use a style that uses execute at end cell to draw a horizontal line at the top or bottom edge of selected cells. By applying this style to complete using row <number>/.style, you can get an effect similar to \hline:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}

\tikzset{toprule/.style={%
        execute at end cell={%
            \draw [line cap=rect,#1] (\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn.north west) -- (\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn.north east);%
        }
    },
    bottomrule/.style={%
        execute at end cell={%
            \draw [line cap=rect,#1] (\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn.south west) -- (\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn.south east);%
        }
    }
}

\begin{tikzpicture}
\matrix [matrix of nodes,
    row sep=-\pgflinewidth,
    column sep=-\pgflinewidth,
    nodes={rectangle,minimum width=3em,outer sep=0pt},
    row 1/.style={toprule=thick,bottomrule},
    row 3/.style={bottomrule=thick}]
{
0   & 6 & 5\\
1   & 3 & 7\\
21 & 22 & 23\\
};
\end{tikzpicture}
\end{document}

matrix of cells with horizontal lines

share|improve this answer
    
A very nice solution. I like having the option to specify the line width. This gives the whole thing almost the feel of booktabs. –  Martin H Jun 14 '11 at 8:38

The following might at least decrease the burden of putting the nodes etc. (I hope). In fact, it is similar to what you have already ruled out as a bad solution, but still it sweeps the ugliness under the rug and does not introduce new nodes other than the tikz matrix has already defined.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\newcommand{\hhlline}[3]{\draw (#1-#2-1.south west) -- (#1-#2-#3.south east);}
\begin{document}
\begin{tikzpicture}
\node[matrix of math nodes] (mymat) {
0   &a  & 6 \\
1   &b  & 3 \\
2   &c  & 9 \\
};
\hhlline{mymat}{1}{2};
\hhlline{mymat}{2}{3};
\end{tikzpicture}
\end{document}

enter image description here

So, you use the command \hhlline with three arguments, the name of the matrix, the row you want to draw the line under it and the number of columns you want to keep drawing.

I am pretty sure that this can further be improved but I am not very good at accessing the internal variables of the matrix environment and using it inside the command automatically. Anyway, hope it helps. Cheers

And last minute addition: Jake's solution looks quite nice.

share|improve this answer

There is an issue with Jake's code if the nodes are different sizes. This can be fixed using the matrixcells part of the TeX-SX TikZ package (currently available from launchpad) to put the lines in after the matrix has been drawn and positioned correctly. Here's a sample of the code, including an example showing where Jake's code breaks down.

Result:

hlines and tikz matrices

Code:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\usepackage{matrixcells}
\begin{document}


\tikzset{toprule/.style={%
        execute at end cell={%
            \draw [line cap=rect,#1] (\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn.north west) -- (\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn.north east);%
        }
    },
    bottomrule/.style={%
        execute at end cell={%
            \draw [line cap=rect,#1] (\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn.south west) -- (\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn.south east);%
        }
    },
}

\makeatletter
\tikzset{
    hlines/.style={%
      label cells,
      initialise hlines,
      append after command={%
        \pgfextra{\pgfmathtruncatemacro{\hline@cols}{\pgfmatrixcurrentcolumn - 1}}%
        \ifx\hline@rows\pgfutil@empty
        \else
        \foreach \hline@row in \hline@rows {
          \pgfextra{\edef\hline@temp{
          (\tikzlastnode-cell-\hline@row-1.north west) edge[\csname hline@row@\hline@row\endcsname] (\tikzlastnode-cell-\hline@row-\hline@cols.north east)}}
          \hline@temp
        }
        \fi
      }
    },
    initialise hlines/.code={
      \global\let\hline@rows=\pgfutil@empty
      \let\hline=\hline@inmatrix
    }
}

\newcommand\hline@inmatrix[1][]{%
    \ifx\hline@rows\pgfutil@empty
     \xdef\hline@rows{\the\pgfmatrixcurrentrow}%
    \else
     \xdef\hline@rows{\hline@rows,\the\pgfmatrixcurrentrow}%
    \fi
    \expandafter\xdef\csname hline@row@\the\pgfmatrixcurrentrow\endcsname{#1}%
}
\makeatother

\begin{tikzpicture}
\matrix [matrix of nodes,
    row sep=-\pgflinewidth,
    column sep=-\pgflinewidth,
    nodes={rectangle,minimum width=3em,outer sep=0pt},
    row 1/.style={toprule=thick,bottomrule},
    row 3/.style={bottomrule=thick}] (a)
{
\(\frac12\)   & 6 & 5\\
1   & 3 & 7\\
21 & 22 & 23\\
};
\matrix [matrix of nodes,hlines,anchor=north] (mm) at (a.south)
{
\(\frac12\)   & 6 & 5\\ \hline[thick]%
1   & 3 & 7\\ \hline
21 & 22 & 23\\
};
\end{tikzpicture}
\end{document}
share|improve this answer
    
Ah, I love it when solutions to different problems play together like that. Very nice! –  Jake Jun 20 '11 at 7:52
    
A good hint, thanks for investigating this further –  Martin H Jun 20 '11 at 10:43

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.