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.

I am looking for a convenient way to set the background of tabular cells. I'd like to do two things: (1) Set the background shaded in a color (2) Set the background hatched

I learned that the TikZ package provides means to do this but I am unable to come up with a solution that does not use matrices (such as here: http://www.texample.net/tikz/examples/timetable/) but instead uses the tabular package.

Here's what I'd like to do:

\documentclass{article}
\begin{document}
\begin{tabular}{|l|l|l|}
\hline
  1 & \setBGGray 2 & 3 \\\hline
  4 & 5 & 6 \\\hline
  7 & \setBGHatched 8 & 9 \\\hline
\end{tabular}
\end{document}

The output should look like this:

enter image description here

Can someone please help me achieving this using tabular (or tabularx) and TikZ?

share|improve this question

2 Answers 2

My solution is based on Highlight elements in the matrix. Indeed, one possibility here is to exploit matrices.

The code:

\documentclass[a4paper,12pt]{article}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{calc,matrix,patterns,shadings,backgrounds}
\pgfdeclarelayer{myback}
\pgfsetlayers{myback,background,main}

\tikzset{myfillcolor/.style = {draw,fill=#1}}%

\NewDocumentCommand{\highlight}{O{blue!40} m m}{%
\draw[myfillcolor=#1] (#2.north west)rectangle (#3.south east);
}

\NewDocumentCommand{\vshade}{O{blue!40} O{white} m m}{%
\draw[bottom color =#1,top color=#2] (#3.north west)rectangle (#4.south east);
}

\NewDocumentCommand{\oshade}{O{blue!40} O{white} m m}{%
\draw[right color =#1,left color=#2] (#3.north west)rectangle (#4.south east);
}

\NewDocumentCommand{\inshade}{O{blue!40} O{white} m m}{%
\draw[inner color =#1,outer color=#2] (#3.north west)rectangle (#4.south east);
}

\NewDocumentCommand{\fillpattern}{O{north west lines} O{blue!50} m m}{%
\draw[pattern=#1, pattern color=#2] (#3.north west)rectangle (#4.south east);
}

\begin{document}
\begin{tikzpicture}
\matrix (m)[matrix of nodes, style={nodes={rectangle,draw,minimum width=3em}}, minimum height=3em, row sep=-\pgflinewidth, column sep=-\pgflinewidth,ampersand replacement =\&]
{
1 \& 2 \& 3 \\
4 \& 5 \& 6 \\
7 \& 8 \& 9 \\
};

\begin{pgfonlayer}{myback}
\highlight{m-1-1}{m-1-1}
\vshade{m-2-2}{m-2-2}
\vshade[white][red]{m-2-3}{m-2-3}
\oshade{m-1-3}{m-1-3}
\oshade[white][orange]{m-1-2}{m-1-2}
\inshade[orange][white]{m-2-1}{m-2-1}
\fillpattern{m-3-2}{m-3-2}
\fillpattern[dots][green!50!black]{m-3-1}{m-3-1}
\fillpattern[sixpointed stars][violet!50]{m-3-3}{m-3-3}
\end{pgfonlayer}
\end{tikzpicture}

\end{document}

The result is (please forgive my bad colors :)):

enter image description here

Some explanations

The basic idea here, as it is said before, is to exploit matrices, thus the first thing to do is to draw the grid around numbers. This has been achieved by the options style={nodes={rectangle,draw,minimum width=3em}}, minimum height=3em, row sep=-\pgflinewidth, column sep=-\pgflinewidth.

Each element is colored in background by means of the background library such that the coloring does not affect too much the number visibility (beware of the patterns that are a bit problematic).

On the bases of the result you want to achieve, you should use a different command:

  1. \highlight is the most simple command and it colors the whole part;
  2. \vshade allows to insert a vertical shading;
  3. \oshade is the equivalent for the horizontal shading;
  4. \inshade allows to achieve a radial shading;
  5. \fillpattern inserts a pattern.

By means of TikZ matrices you can highlight an element by using the syntax name_matrix-row-colum: in our case an element could be m-1-1. All commands are designed to fill an area corresponding to (element.north west)rectangle (element.south east) and allow you to customize the coloring. Actually, it is even possible to select a bigger area, for instance two or more numbers; an example of this selection type could be:

\vshade{m-1-1}{m-2-2}

to color the correspondin areas of 1, 2, 4, 5.

For what concern the \fillpattern, you can even select which pattern style use (first optional argument) and its color (second optional argument).

The same result could be achieved by means of the fit library:

\documentclass[a4paper,12pt]{article}
\usepackage{tikz}
\usetikzlibrary{calc,matrix,patterns,shadings,backgrounds,fit}
\pgfdeclarelayer{myback}
\pgfsetlayers{myback,background,main}

\begin{document}
\begin{tikzpicture}
\matrix (m)[matrix of nodes, style={nodes={rectangle,draw,minimum width=3em}}, minimum height=3em, row sep=-\pgflinewidth, column sep=-\pgflinewidth,ampersand replacement =\&]
{
1 \& 2 \& 3 \\
4 \& 5 \& 6 \\
7 \& 8 \& 9 \\
};

\begin{pgfonlayer}{myback}
\node[fit=(m-1-1),fill=blue!40,inner sep=0cm]{};
\node[fit=(m-2-2),bottom color=blue!40,top color= white,inner sep=0cm]{};
\node[fit=(m-2-3),bottom color=white,top color= red,inner sep=0cm]{};
\node[fit=(m-1-3),right color=blue!40,left color= white,inner sep=0cm]{};
\node[fit=(m-1-2),right color=white,left color= orange,inner sep=0cm]{};
\node[fit=(m-2-1),outer color=white,inner color= orange,inner sep=0cm]{};
\node[fit=(m-3-2),pattern=north west lines, pattern color=blue!50,inner sep=0cm]{};
\node[fit=(m-3-1),pattern=dots, pattern color=green!50!black,inner sep=0cm]{};
\node[fit=(m-3-3),pattern=sixpointed stars, pattern color=violet!50,inner sep=0cm]{};
\end{pgfonlayer}
\end{tikzpicture}

\end{document}
share|improve this answer

My answer to Gradient color in one cell of a table produces shaded cells and can easily be adapted to produce hatched patterns. This solution works with tabular, tabularx (tabulary will also be OK I imagine, although I didn't test it) and with \multicolumn:

\documentclass[10pt]{article}
\usepackage[margin=2cm]{geometry} % just for the example 
\usepackage{fourier} 
\usepackage[table]{xcolor} 
\usepackage{array}
\usepackage{tabularx}
\usepackage{tikz}
\usepackage{lipsum}
\usetikzlibrary{calc,shadings,patterns}

% Andrew Stacey's code from
% http://tex.stackexchange.com/a/50054/3954
\makeatletter
\tikzset{%
  remember picture with id/.style={%
    remember picture,
    overlay,
    save picture id=#1,
  },
  save picture id/.code={%
    \edef\pgf@temp{#1}%
    \immediate\write\pgfutil@auxout{%
      \noexpand\savepointas{\pgf@temp}{\pgfpictureid}}%
  },
  if picture id/.code args={#1#2#3}{%
    \@ifundefined{save@pt@#1}{%
      \pgfkeysalso{#3}%
    }{
      \pgfkeysalso{#2}%
    }
  }
}

\def\savepointas#1#2{%
  \expandafter\gdef\csname save@pt@#1\endcsname{#2}%
}

\def\tmk@labeldef#1,#2\@nil{%
  \def\tmk@label{#1}%
  \def\tmk@def{#2}%
}

\tikzdeclarecoordinatesystem{pic}{%
  \pgfutil@in@,{#1}%
  \ifpgfutil@in@%
    \tmk@labeldef#1\@nil
  \else
    \tmk@labeldef#1,(0pt,0pt)\@nil
  \fi
  \@ifundefined{save@pt@\tmk@label}{%
    \tikz@scan@one@point\pgfutil@firstofone\tmk@def
  }{%
  \pgfsys@getposition{\csname save@pt@\tmk@label\endcsname}\save@orig@pic%
  \pgfsys@getposition{\pgfpictureid}\save@this@pic%
  \pgf@process{\pgfpointorigin\save@this@pic}%
  \pgf@xa=\pgf@x
  \pgf@ya=\pgf@y
  \pgf@process{\pgfpointorigin\save@orig@pic}%
  \advance\pgf@x by -\pgf@xa
  \advance\pgf@y by -\pgf@ya
  }%
}
\newcommand\tikzmark[2][]{%
\tikz[remember picture with id=#2] {#1;}}
\makeatother
% end of Andrew's code

\newcommand\ShadeCell[4][0pt]{%
  \begin{tikzpicture}[overlay,remember picture]%
    \shade[#4] ( $ (pic cs:#2) + (0pt,1.9ex) $ ) rectangle ( $ (pic cs:#3) + (0pt,-#1*\baselineskip-.8ex) $ );
  \end{tikzpicture}%
}%

\newcommand\HatchedCell[4][0pt]{%
  \begin{tikzpicture}[overlay,remember picture]%
    \fill[#4] ( $ (pic cs:#2) + (0,1.9ex) $ ) rectangle ( $ (pic cs:#3) + (0pt,-#1*\baselineskip-.8ex) $ );
  \end{tikzpicture}%
}%

\newcommand\Text{Quisque ullamcorper placerat ipsum. Cras nibh. Lorem ipsum dolor sit amet.}

\begin{document}

\ShadeCell{start1}{end1}{%
  top color=gray!60,bottom color=gray!20}
\ShadeCell{start2}{end2}{%
  left color=gray!50,right color=gray!20}
\HatchedCell{start3}{end3}{%
  pattern color=black!70,pattern=north east lines}

\noindent\begin{tabular}{| c | c | c |}
\hline
1 & \multicolumn{1}{!{\hspace*{-0.4pt}\vrule\tikzmark{start1}}c!{\vrule\tikzmark{end1}}}{2} & 3 \\
\hline
\multicolumn{1}{!{\vrule\tikzmark{start2}}c!{\vrule\tikzmark{end2}}}{4} & 5 & 6 \\
\hline
7 & 8 & \multicolumn{1}{!{\hspace*{-0.4pt}\vrule\tikzmark{start3}}c!{\vrule\tikzmark{end3}}}{9} \\
\hline
\end{tabular}

\vspace{10pt}

\ShadeCell[3]{start4}{end4}{%
  top color=gray!40}
\HatchedCell[3]{start5}{end5}{%
  pattern color=gray!40,pattern=vertical lines}
\HatchedCell[3]{start6}{end6}{%
  pattern color=gray!50,pattern=north east lines}

\noindent\begin{tabularx}{.6\textwidth}{| X | X | X |}
\hline
\Text & \multicolumn{1}{!{\hspace*{-0.4pt}\vrule\tikzmark{start4}}X!{\vrule\tikzmark{end4}}}{\Text} & \Text \\
\hline
\multicolumn{1}{!{\vrule\tikzmark{start5}}X!{\vrule\tikzmark{end5}}}{\Text} & \Text & \Text \\
\hline
\Text & \multicolumn{2}{!{\hspace*{-0.4pt}\vrule\tikzmark{start6}}>{\hsize=2\hsize}X!{\vrule\tikzmark{end6}}}{\Text} \\
\hline
\end{tabularx}

\end{document}

enter image description here

And the numeric matrix zoomed in:

enter image description here

If you need to repeatedly use the same hatching in multiple cells, the above approach is a little clumsy. But you can define a counter and a single command that does all the neccessary stuff (I removed the vertical lines as there were some glitches I could not fix easily, but you should not use vertical lines in tables anyway ;-):

\newcounter{hatchNumber}
\setcounter{hatchNumber}{1}
\newcommand\myHatch[2]{
    \multicolumn{1}{
        !{\HatchedCell{startMyHatch\arabic{hatchNumber}}{endMyHatch\arabic{hatchNumber}}{%
                pattern color=black!70,pattern=north east lines}
            \tikzmark{startMyHatch\arabic{hatchNumber}}}
            #1
        !{\tikzmark{endMyHatch\arabic{hatchNumber}}}}
        {#2} 
      \addtocounter{hatchNumber}{1}
}


% Using the simplified command myHatch

\noindent\begin{tabular}{ c  c  c }
\hline
1 & \myHatch{c}{2} & 3 \\
\myHatch{c}{4} & 5 & \myHatch{c}{6} \\
share|improve this answer
    
That is a nice solution! There is only one minor bug, and that is that the border of the shaded or hatched cells is thicker than the border of the other cells. I think that has to do with using a tikz rectangle. Is it possible to paint a borderless rectangle? –  Michael Aug 14 '12 at 14:18
    
@Michael yes, now I've updated my answer correcting this. If I have time I'll add some other improvements. –  Gonzalo Medina Aug 14 '12 at 15:36
    
Thank you very much for the update. There is still a minor bug. If you replace your text: \newcommand\Text{Quisque ullamcorper placerat ipsum. Cras nibh. Lorem ipsum dolor sit amet.} with this one: \newcommand\Text{Quisque ullamcorper placerat ipsum. Cras nibh. Lorem ipsum dolor sit amet. Quisque ullamcorper placerat ipsum. Cras nibh. Lorem ipsum dolor sit amet} you will see that the background does not fill the whole cell, i.e. if the text is longer, than there will be linebreaks which this aproach seems to be unable to handle. –  Michael Aug 14 '12 at 17:12
1  
@Michael that's not a bug; if the text spans more than one line, you need to use the optional argument of \ShadeCell or \HatchedCell. In my original answer I exaplain how to use the command, but basically, if the text spans n lines (n>1) you need to use n-1 as the optional argument. –  Gonzalo Medina Aug 14 '12 at 17:21
    
I'm getting a weird error when I try to compile the solution. pdfTeX error: pdflatex (file putr8a.pfb): cannot open Type 1 font file for reading. I'm afraid I have no idea how to debug this. What part of the solution causes this? I'd very much appreciate any pointers –  Joost May 27 '13 at 19:37

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.