# How to generate a table with square cells?

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?

Here's my attempt using TikZ:

\documentclass{article}
\usepackage[x11names]{xcolor}
\usepackage{tikz}
\usepackage{fontspec}
\setmainfont{Libertinus Serif}
\begin{document}
\begin{tikzpicture}
\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};
\end{tikzpicture}
\end{document}


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}
\usetikzlibrary{calc}
\usetikzlibrary{matrix}

\begin{document}
\begin{tikzpicture}
\matrix(D)[matrix of nodes,nodes in empty cells,
row sep=-\pgflinewidth,column sep=-\pgflinewidth,
nodes={anchor=center},
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}};
\end{tikzpicture}
\end{document}


With {NiceTabular} of nicematrix.

\documentclass{article}
\usepackage{nicematrix}

\begin{document}

\setlength{\tabcolsep}{0pt}
\begin{NiceTabular}{c@{\enskip}c@{\enskip}wc{1cm}wc{1cm}}[colortbl-like]
&         & \Block{1-2}{Predicted Class} \\
&         & \rotate Sample A & \rotate Sample B \\
\Block{2-1}{\rotate Actual Class}%
\rule[-4mm]{0pt}{1cm}
& Sample A& \Block[hvlines]{2-2}{}\Block[fill=green!15]{}{1696} & 38 \\
\rule[-4mm]{0pt}{1cm}
& Sample B& 30 & \Block[fill=green!15]{}{1275}\\
\end{NiceTabular}

\end{document}


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

You can start from this code:

\documentclass{article}

\usepackage{xcolor}

\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 }}

\begin{document}

\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}
\hrule}}

\end{document}


\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{matrix}
\begin{document}
\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}}}}

\begin{tikzpicture}[myset/.list={(2,2),(3,3)},mysett/.list={(2,1),(3,1)}]
\matrix [matrix of nodes]
{
& \rotatebox{90}{\bfseries text} & \rotatebox{90}{\bfseries text} \\
Sample  & 1000 & 900 \\
Sample  & 90 & 2000 \\
};
\end{tikzpicture}
\end{document}

• … except for the cells notably being not square … – Ingmar Apr 10 at 6:29