Convert a NumPy array to LaTeX

LaTeX matrices and determinants from NumPy arrays
python
numpy
latex
Author

Enrique Pérez Herrero

Published

August 2, 2023

Sierra de las Nieves (Málaga)

Convert Numpy array to LaTeX

Sometimes, when you are writing a statistics or a math article, you must go through a tedious process of typing and testing numerous lines of text until your code works. This can be especially boring when dealing with long matrices. If you want to improve your productivity, automating this process comes in very handy, and Python is particularly useful for that.

Functions for matrices and determinants

The functions matrix2latex and det2latex generate an indented LaTeX string that can be copied or directly rendered in your math article.

The INDENT_SPACES parameter specifies the number of spaces used for indentation.

Code
import numpy as np

INDENT_SPACES = 3

def indent(num_indent=1):
    """
    Number of spaces for indentation
    """
    return num_indent * INDENT_SPACES * " "

def matrix2latex(matrix):
    """
    Convert a NumPy array to LaTeX code as a matrix
    """
    left_latex = r"\left(" + "\n" + indent(1) + r"\begin{array}"
    right_latex = indent(1) + r"\end{array}" + "\n" + r"\right)"
    m_cols = matrix.shape[1]
    array_cols = "{" + "r" * m_cols + "}\n"
    elements_latex = ""
    for row in matrix:
        elements_latex = \
          elements_latex + indent(2) + " & ".join([str(x) for x in row]) + \
            r" \\ " + "\n"
    latex = left_latex + array_cols + elements_latex + right_latex
    return f"$$\n{latex}\n$$"

def det2latex(matrix):
    """
    Convert a NumPy array to LaTeX code as a determinant
    """
    left_latex = r"\begin{vmatrix}" + "\n"
    right_latex = r"\end{vmatrix}"
    m_cols = matrix.shape[1]
    elements_latex = ""
    for row in matrix:
        elements_latex = \
          elements_latex + indent(1) + " & ".join([str(x) for x in row]) + \
            r" \\ " + "\n"
    latex = left_latex + elements_latex + right_latex
    return f"$$\n{latex}\n$$"

Output string

Using the NumPy function np.eye, we can create an identity matrix of the desired dimensions, making it a convenient tool for testing our functions.

Code
print(matrix2latex(np.eye(3, dtype=int)))
$$
\left(
   \begin{array}{rrr}
      1 & 0 & 0 \\ 
      0 & 1 & 0 \\ 
      0 & 0 & 1 \\ 
   \end{array}
\right)
$$

Rendering output in a document

If you are working in a Jupyter notebook, you can render a LaTeX string using the Math function from the IPython library, which can be imported as follows:

Code
from IPython.display import Math

If you are writing a Python chunk in a Quarto file in RStudio, you need to include the option #| output: asis at the top of the code chunk. This option determines how the output is rendered in the final document.

Code
print(det2latex(np.eye(3, dtype=int)))

|100010001|

Code
# Identity 4x4 matrix
identity_4 = np.eye(4, dtype=int)
identity_4_latex = r"$$I_4 = " + f"{matrix2latex(identity_4)}"[2:]
print(identity_4_latex)

I4=(1000010000100001)

Rendering the output to a file

The LaTeX string can be rendered and saved to a file using the following function, which is based on the SymPy library.

Code
from sympy import preview

def latex2png(latex, filename, fontsize=300):
    """
    Render LaTeX code to a PNG image
    """
    return preview(latex,
                   viewer='file',
                   filename=filename,
                   euler=False,
                   dvioptions=['-D', f'{str(fontsize)}'])

Other types of automated matrices

Matrices with numbered elements

Code
def element_matrix(n, notation=r"x"):
    """
    Matrix with elements in algebraic notation 
    """
    vec_function = \
      np.vectorize(lambda i, j: notation + "_{" + f"{i + 1}{j + 1}" + "}")
    return np.fromfunction(vec_function,
                           shape=(n, n),
                           dtype=int)
Code
print(matrix2latex(element_matrix(5, notation=r"\theta")))

(θ11θ12θ13θ14θ15θ21θ22θ23θ24θ25θ31θ32θ33θ34θ35θ41θ42θ43θ44θ45θ51θ52θ53θ54θ55)

Triangular matrices

  • Upper Triangular Matrix: In an upper triangular matrix, all elements below the main diagonal are zero.
Code
def up_triangular_matrix(n):
    """
    Upper Triangular matrix filled with ones and zeros
    """
    return np.fromfunction(lambda i, j:  1 * np.less_equal(i , j),
                           shape=(n, n),
                           dtype=int)
  • Lower Triangular Matrix: In a lower triangular matrix, all elements above the main diagonal are zero.
Code
def lw_triangular_matrix(n):
    """
    Lower Triangular matrix filled with ones and zeros
    """
    return np.fromfunction(lambda i, j:  1 * np.greater_equal(i , j),
                           shape=(n, n),
                           dtype=int)
Code
print(matrix2latex(up_triangular_matrix(5)))

(1111101111001110001100001)