# How to add a caption to a PyLaTeX Tabular table

I would like to add a caption to a Tabular table in PyLaTeX but I'm not sure how I can do this. It seems possible using the table class but all the examples make use of a Tabular element.

Basically I want something like the following:

from pylatex import Document, Section, Subsection, Tabular, MultiColumn,\
MultiRow

doc = Document("multirow")
section = Section('Multirow Test')

test1 = Subsection('MultiColumn')

table1 = Tabular('|c|c|c|c|')
table1.add_row((1, 2, 3, 4))

test1.append(table1)
section.append(test1)

doc.append(section)
doc.generate_pdf(clean_tex=False)

• Hello! It would be a lot more helpfull to add an MWE. Pages of documentations for reference are great, but this requires anybody willing to investigate to create his own example. I am not too familiar with this, but it seems that you want a .tex fiel to be output. Well, you could (manually) add float environment table to wrap any tabular ; like \begin{table}[htb] --your tabular code-- \caption{caption text} \end{tabular} ; or you could use package captionof ; which allows you to add caprions to non-floating objects (to simple tabular in your case). – Tomáš Kruliš Jan 23 at 9:55
• To further expand, I would suggest you to go the other way - If you write document in LaTeX, use primarily LaTeX and embedd the output with PythonTeX package; as learning Python I found it easier than the other way around. – Tomáš Kruliš Jan 23 at 9:59
• Thanks for the comment, but I really do not want to edit things from the latex side. My goal is to automatically generate python reports from the python side. I'm certain one can add captions to PyLatex without resorting to changing tools – Daniel Marchand Jan 23 at 10:40
• Well, from doc, even from source, is not clear to me, how to "wrap" tabular code inside table class. If you are more experienced with python and know how to do that (well, I dont know how to utilize the **kwargs argument, since I dont know which keys make sense), then you have to just wrap tabular code within table just as I wrote earlier. From TeX side it is a piece of cake, If you would just add required string to your TeX generating script, then you are OK. Other than that, I dont know. Hopefully, someone else will do. – Tomáš Kruliš Jan 23 at 11:10

The pylatex library provides a Table() class as was noted in the question. This class generates the LaTeX table environment, for example:

table1 = Table(position="htb")


generates

\begin{table}[htb]%
\end{table}


The tabular environment can be appended to the Table() object in PyLaTeX, similar to the way a subsection is appended to a section. In turn the table can be appended to a subsection. For example:

test1 = Subsection('MultiColumn')
table1 = Table(position="htb")
tabular1 = Tabular('|c|c|c|c|')
# fill tabular
table1.append(tabular1)
test1.append(table1)


The Table() class has a function add_caption() to add a caption. If you also want to add a label then you need a separate object from the class Label() and append this to the table object. Further objects or code can be appended to the table, for example a \centering command to center the tabular in the middle of the page.

MWE:

from pylatex import Document, Section, Subsection, \
Table, Tabular, MultiColumn, MultiRow, Label, Ref, NoEscape

doc = Document("multirow")
section = Section('Multirow Test')

test1 = Subsection('MultiColumn')
# make table
table1 = Table(position="htb")
# make tabular
tabular1 = Tabular('|c|c|c|c|')
tabular1.add_row((1, 2, 3, 4))
# horizontally center tabular on page
table1.append(NoEscape(r'\centering'))
# append tabular to table
table1.append(tabular1)
# add caption and label
label1 = Label("tab1")
table1.append(label1)
# append table to subsection
test1.append(table1)
section.append(test1)
# create and print reference to table
ref1 = Ref("tab1")
section.append("The numbers are in Table ")
section.append(ref1)
section.append(".")

doc.append(section)
doc.generate_pdf(clean_tex=False)


Generated LaTeX:

\documentclass{article}%
\usepackage[T1]{fontenc}%
\usepackage[utf8]{inputenc}%
\usepackage{lmodern}%
\usepackage{textcomp}%
\usepackage{lastpage}%
\begin{document}%
\normalsize%
\section{Multirow Test}%
\label{sec:Multirow Test}%
\subsection{MultiColumn}%
\label{subsec:MultiColumn}%

\begin{table}[htb]%
\centering%
\begin{tabular}{|c|c|c|c|}%
\hline%
1&2&3&4\\%
\hline%
\end{tabular}%
\caption{My Table Caption}%
\label{tab1}%
\end{table}

The numbers are in Table %
\ref{tab1}%
.
\end{document}


Result:

Well, Marijn beat me to it. Anyway, I just wanted to point out, that you can nest the tabulars inside of the tables (and the other structures too). That way, you get better structured code and don't need to declare variables explicitly all the time:

from pylatex import Document, Section, Subsection, Tabular, Table, MultiColumn, MultiRow

doc = Document('multirow')
with doc.create(Section('Multirow Test')):
with doc.create(Subsection('MultiColumn')):
with doc.create(Table(position='h!')) as table:
with doc.create(Tabular('|c|c|c|c|')) as tabular:
tabular.add_row((1, 2, 3, 4))

doc.generate_pdf(clean_tex=False)


As you can see in the example below, you don't need to invent new variable names (tabular1, tabular2, etc.) and you don't have to .append everything in the end:

from pylatex import Document, Section, Subsection, Tabular, Table, MultiColumn, MultiRow

doc = Document('multirow')
with doc.create(Section('Multirow Test')):
with doc.create(Subsection('MultiColumn')):
with doc.create(Table(position='h!')) as table:
with doc.create(Tabular('|c|c|c|c|')) as tabular: