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.

Is it possible to make TikZ matrix cells span multiple rows/columns, like they can in LaTeX tables using \multirow/\multicolumn? Specifically, I'd like to typeset something like the following in a TikZ matrix:

header1  longcell1   longcell2
header2  cellA cellB cellC cellD
header3  X     Y     Z     W
share|improve this question

3 Answers 3

Here's a method of doing this that tries to take into account the length of the multicolumn entry. It's not all that sophisticated as all it does is assign a factor of the length of the desired entry to each of the columns (a better approach would be to ensure that the total length was at least the length of the multicolumn entry). It works by hooking in to the \pgfmatrixendcode and \pgfmatrixemptycode macros to adjust their widths accordingly. We have to be a bit sneaky as those macros are executed before the widths are actually known, so what they actually do is set stuff up so that when the widths are known then they are adjusted.

Here's the code:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}

\makeatletter
\newdimen\multi@col@width
\newdimen\multi@col@margin
\newcount\multi@col@count
\multi@col@width=0pt

\tikzset{
  multicol/.code={%
    \global\multi@col@count=#1\relax
    \global\let\orig@pgfmatrixendcode=\pgfmatrixendcode
    \global\let\orig@pgfmatrixemptycode=\pgfmatrixemptycode
    \def\pgfmatrixendcode##1{\orig@pgfmatrixendcode%
      ##1%
      \pgfutil@tempdima=\pgf@picmaxx
      \global\multi@col@margin=\pgf@picminx
      \advance\pgfutil@tempdima by -\pgf@picminx
      \divide\pgfutil@tempdima by #1\relax
      \global\multi@col@width=\pgfutil@tempdima
      \pgf@picmaxx=.5\multi@col@width
      \pgf@picminx=-.5\multi@col@width
      \global\pgf@picmaxx=\pgf@picmaxx
      \global\pgf@picminx=\pgf@picminx
      \gdef\multi@adjust@position{%
        \setbox\pgf@matrix@cell=\hbox\bgroup
        \hfil\hskip-\multi@col@margin
        \hfil\hskip-.5\multi@col@width
        \box\pgf@matrix@cell
        \egroup
      }%
      \gdef\multi@temp{\aftergroup\multi@adjust@position}%
      \aftergroup\multi@temp
    }
    \gdef\pgfmatrixemptycode{%
      \orig@pgfmatrixemptycode
      \global\advance\multi@col@count by -1\relax
      \global\pgf@picmaxx=.5\multi@col@width
      \global\pgf@picminx=-.5\multi@col@width
      \ifnum\multi@col@count=1\relax
       \global\let\pgfmatrixemptycode=\orig@pgfmatrixemptycode
      \fi
    }
  }
}
\makeatother

\begin{document}
\begin{tikzpicture}
\matrix[matrix of nodes,nodes={draw}] {
A &|[multicol=3]| A long entry spanning three columns &&&  A \\
A B &|[multicol=2]| A shorter entry &&  A & D E F \\
A B & A B & A B C D E F & A B\\
};
\end{tikzpicture}
\end{document}

Here's the result:

multi row entries in TikZ matrix

An important thing to note in the code is that the multirow entry is followed by the requisite number of empty entries (which makes me think that this probably wouldn't interact well with a style that put something in every empty node, incidentally).

There are obviously many ways in which this could be improved! And it only works for columns.


Update 2013-04-12 I've been informed (by email) that the following fixes an issue with centring the content in cells. Change the start of the definition of \multi@adjust@position to:

  \gdef\multi@adjust@position{%
     \setbox\pgf@matrix@cell=\hbox\bgroup
     \hfil\hskip-1.5\multi@col@margin
     \hfil\hskip-.5\multi@col@width
share|improve this answer
    
Excellent, as usual! It also almost directly works with stuff like the table in the horizontal row separation line in tikz matrix. However, I need to manually specify the width of the combined cell: 0 &|[multicol=2,minimum width=6em]| 6 &\\ , otherwise it's too small. Easily fixed, or too special a case to consider? –  Jake Jun 19 '11 at 21:37
    
WOW!! Can you tell me how can I learn all internal PGF command? –  Azoun Jun 19 '11 at 21:40
    
@Jake: I just took a look at that question. I found an issue with your answer there ... –  Loop Space Jun 20 '11 at 7:44
2  
@Azoun: browse the code! And answer questions here. –  Loop Space Jun 20 '11 at 7:45
    
Dear @AndrewStacey, how can I underline multicolumns automatically as I stated in tex.stackexchange.com/questions/113203/… –  Kadir May 8 '13 at 12:06

You could use the anchors of the matrix to place a multicolumn node over the matrix.

An approach would be to nest matrices, but afaik TikZ doesn't support that yet.

share|improve this answer

A very basic approach could be to use the fit library to create nodes that surround empty matrix cells.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fit,matrix}

\begin{document}
  \begin{tikzpicture}
    \matrix (table) [%
      matrix of nodes,
      nodes in empty cells
    ] {%
      A & B & C & D \\
      E &   &   & G \\
      H & I & J &   \\
      K & L & M &   \\
   };
    \node[fit=(table-2-2)(table-2-3)]{F};
    \node[fit=(table-3-4)(table-4-4)]{N};
  \end{tikzpicture}
\end{document}

But it first becomes a bit ugly when you e. g. try to fill those cells with a color. So you will need some more adjustments.

share|improve this answer

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.