I am looking for a way to create a table in LaTeX as shown in the figure below. Some of the design aspects of the table are:

  • The cells containing the numbers must be square (using a normal table command gives me rectangular cells)
  • All text is middle aligned

How do I generate such a table?

Sameple Table


Here's my attempt using TikZ:

\setmainfont{Libertinus Serif}
\draw[very thin, fill=SpringGreen1] (-0.5,-0.5) rectangle +(1,1);
\draw[very thin, fill=SpringGreen1] (0.5,-1.5) rectangle +(1,1);
\draw[very thin] (-0.5,-1.5) rectangle +(1,1);
\draw[very thin] (0.5,-0.5) rectangle +(1,1);
\node at (0,0) {1696\strut};
\node at (1,0) {38\strut};
\node at (0,-1) {30\strut};
\node at (1,-1) {1275\strut};
\node[rotate=90, anchor=west] at (0,0.5) {Sample A};
\node[rotate=90, anchor=west] at (1,0.5) {Sample B};
\node[anchor=east] at (-0.5,0) {Sample A};
\node[anchor=east] at (-0.5,-1) {Sample B};
\node at (0.5,2.4) {Predicted Class};
\node[rotate=90] at (-2.5,-0.5) {Actual Class};

enter image description here

A few notes:

  • The shade of green used can be improved, have a look at what xcolor has to offer.
  • Pretty much everything is placed manually, which is about the level of TikZ skill I currently possess. (But for a small table like this, that strikes me as acceptable.)
  • The \struts are there to ensure that the LHS labels are vertically aligned with the table cell contents.
  • I used Libertinus Serif because it looks similar to the font in your image --- but also because it's just beautiful in general.

EDIT: You may actually want to add \struts to the LHS labels ("Sample A" and "Sample B") as well; I have a feeling the vertical spacing is still very slightly off there.


Another option with matrix library could be:

\documentclass {standalone}
\usepackage    {tikz}

  \matrix(D)[matrix of nodes,nodes in empty cells,
             row sep=-\pgflinewidth,column sep=-\pgflinewidth,
             row 1/.style={minimum height=1cm},
             row 2/.style={minimum height=2cm},
             row 3/.style={minimum height=1cm},
             row 4/.style={minimum height=1cm},
             column 1/.style={minimum width=1cm},
             column 2/.style={minimum width=2cm},
             column 3/.style={minimum width=1cm},
             column 4/.style={minimum width=1cm},
    &  &  & \\
    &  & \rotatebox{90}{Sample A} & \rotatebox{90}{Sample B}\\
    & Sample A & |[draw,fill=green!20]|1696 & |[draw]|38\\
    & Sample B & |[draw]|30 & |[draw,fill=green!20]|1275\\
  \node at ($(D-1-3)!0.5!(D-1-4)$) {Predicted Class};
  \node at ($(D-4-1)!0.5!(D-3-1)$) {\rotatebox{90}{Actual Class}};

enter image description here


With {NiceTabular} of nicematrix.



&         & \Block{1-2}{Predicted Class} \\
&         & \rotate Sample A & \rotate Sample B \\
\Block{2-1}{\rotate Actual Class}%
& Sample A& \Block[hvlines]{2-2}{}\Block[fill=green!15]{}{1696} & 38 \\
& Sample B& 30 & \Block[fill=green!15]{}{1275}\\


You need several compilations (because nicematrix uses PGF/Tikz nodes under the hood).

Output of the above code


You can start from this code:



\newdimen\sqrw \sqrw=3em
\def\sqrcell#1#2{\vbox{\hrule\hbox to\sqrw{\ifx^#1^\else 
   \textcolor{#1}{\vrule width\sqrw depth.35\sqrw height.65\sqrw \kern-\sqrw}\fi 
   \vrule depth.35\sqrw height.65\sqrw \hss#2\hss\kern.4pt}}}
\def\txt#1{\llap{\bf#1 }}


\hbox{\phantom{\bf Sample A }\vbox{\offinterlineskip
   \hbox{\txt{Sample A}\sqrcell{green}{1696}\sqrcell{}{38}\vrule}
   \hbox{\txt{Sample B}\sqrcell{}{30}\sqrcell{}{1275}\vrule}


enter image description here

    \tikzset{myset/.style args = {(#1,#2)}{%
            row #1 column #2/.style={nodes={fill=green!20}}}},
    \tikzset{mysett/.style args = {(#1,#2)}{%
                row #1 column #2/.style={nodes={font=\bfseries}}}}
        \matrix [matrix of nodes]
                    & \rotatebox{90}{\bfseries text} & \rotatebox{90}{\bfseries text} \\
            Sample  & 1000 & 900 \\
            Sample  & 90 & 2000 \\
  • 6
    … except for the cells notably being not square … – Ingmar Apr 10 at 6:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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