How can I label the columns and rows of a matrix?

I would like to label the columns and rows of a matrix (e.g. I, J, K, L and M) and ideally also provide an overall label for the rows (winner) and the columns (loser).

The corresponding functionality (at least for the column and row labels) seems to be in LaTeX through a variety of packages, e.g. matrices - Matrix with rows and columns labeled - TeX - LaTeX Stack Exchange

1 Like

You may use table to recreate the matrix structure.

$ 
#table(
    columns: (auto,)+(3pt,)+(auto,)*5+(3pt,),
    stroke: none,
    align: (right + horizon,) + (center + horizon,)*7,
    [],[], $I$, $J$, $K$, $L$, $M$, [],
    $I$, table.cell(rowspan: 5, box(stroke: none, inset: (top: -0.5em), $lr("[", size: #875%)$)), $0$, $1$, $0$, $1$, $0$, table.cell(rowspan: 5, box(stroke: none, inset: (top: -0.5em), $lr("]", size: #875%)$)),
    $J$, $0$, $0$, $1$, $0$, $1$,
    [winner  $K$], $1$, $0$, $0$, $1$, $1$,
    $L$, $0$, $1$, $0$, $0$, $0$,
    $M$, $0$, $0$, $0$, $1$, $0$,
  )
 $

I don’t know a method that can automatically adjust the size of delimiters.

1 Like

Thanks for this solution; it does add the ‘winner’ but not the ‘loser’ (but presumably I could do that above the ‘K’ somehow).

It hadn’t occurred to me that I would be able to get the delimiters using a table but your solution is interesting and I could possibly adapt it so the size is calculated programmatically.

There is another solution using the pin-it package. Please check out my reply How to input an excess matrix, where elements "overflow" the parentheses? - #7 by Fe_Y.

Going off of @Fe_Y’s code, you might dynamically set the delimiter height with an approach like this:

#let labelmat(
  collabels,
  rowlabels,
  ..args
) = context {
  let numcols = collabels.len()
  let numrows = rowlabels.len()
  let matentries = args.pos().chunks(numcols)
  let matheight = matentries.map(
    row => calc.max(..row.map(i => measure(i).height))
  ).sum() + 10pt * numrows
  let delimcell(delim) = table.cell(
    rowspan: numrows, 
    box(inset: (top: -5pt, left: -5pt), $lr(delim, size: #matheight)$)
  )
  table(
    columns: (auto, 7pt, ..(auto,) * numcols, 7pt),
    stroke: none,
    ..args.named(),
    [], [], ..collabels, [],
    ..for (rowindx, (rowlab, rowentries)) in rowlabels.zip(matentries).enumerate() {(
      rowlab,
      ..if rowindx == 0 {(delimcell($\[$),)},
      ..rowentries,
      ..if rowindx == 0 {(delimcell($\]$),)},
    )},
  )
}

#labelmat(
  ("a", "b", "c"),
  ("d", "e", "f"),
  $alpha_r display(beta_s / delta)$, $0$, $1$,
  $1$, $2$, $display(sum_2^n i^2)$,
  $1$, $2$, $3$,
  align: center + horizon
)

Screenshot 2025-05-06 at 3.36.12 PM

3 Likes