Search code examples
pythonlabellatexrefpylatex

How to add a reference to a figure in a cell of a latex table in pylatex


I am using pylatex, and I need to add a reference to a labeled figure in a cell of a latex table within the tabular environment using the "add_row" command. Which one is the correct syntax? It seems a simple string does not work.

I tried adding the reference using a simple string, i.e.:

tabular.add_row('P' + str(j), param, 'Figure' + NoEscape('\ref{fig:param' + str(j) + '}'))

or

tabular.add_row('P' + str(j), param, 'Figure' + '\ref{fig:param' + str(j) + '}')

or

tabular.add_row('P' + str(j), param, 'Figure' + str(Ref('param' + str(j))))

Hereafter a minimal reproducible example you can run in Python. Please set HOME_FOLDER with your personal home folder (syntax depending on Windows or Linux, I'm using Linux)


from pylatex import Document, Package, Command, NoEscape, Section, Table, Center, Tabular, Figure, Label
import subprocess
import numpy as np
import matplotlib.pyplot as plt
import os

time = np.arange(0, 10, 0.001)
frequency = 0.2
y1 = np.sin(2*np.pi*frequency*time)
y2 = np.cos(2*np.pi*frequency*time)

HOME_FOLDER = os.path.join('/home', 'Documents')
texFileName = os.path.join(HOME_FOLDER, 'test')

plt.figure()
plt.plot(time, y1)
plt.savefig(os.path.join(HOME_FOLDER, 'firstParam.pdf'))
plt.close()

plt.figure()
plt.plot(time, y2)
plt.savefig(os.path.join(HOME_FOLDER, 'secondParam.pdf'))
plt.close()

geometry_options = {"top": "2.5cm", "left": "2.25cm", "right": "2.25cm", "bottom": "2.0cm"}

doc = Document(texFileName, documentclass="article", document_options=["12pt", "a4paper"], geometry_options=geometry_options)

doc.packages.append(Package('xcolor', 'table'))
doc.packages.append(Package("caption", "font=normalsize, tableposition=below"))
doc.preamble.append(Command('captionsetup', 'skip=1em', 'longtable'))
doc.packages.append(Package('fancyhdr'))
doc.preamble.append(Command('pagestyle', 'fancy'))
doc.preamble.append(Command('fancyhead', '', 'R'))
doc.packages.append(Package('titlesec'))
doc.preamble.append(Command('setcounter', 'secnumdepth', extra_arguments='4'))

doc.packages.append(Package(NoEscape('eso-pic')))
doc.packages.append(Package('adjustbox'))
doc.packages.append(Package('float'))
doc.packages.append(Package('pdfpages'))
doc.packages.append(Package('array'))
doc.packages.append(Package('hyperref', 'hidelinks'))

paramsList = ['firstParam', 'secondParam']

with doc.create(Section("First Section")):

    with doc.create(Table(position='ht')) as table:
        with table.create(Center()) as centered:
            with centered.create(Tabular('|l|c|c|')) as tabular:
                tabular.add_hline()
                for j, param in enumerate(paramsList):
                    tabular.add_row('P' + str(j), param, 'Figure' + '\ref{fig:param' + str(j) + '}')
                    tabular.add_hline()    
            table.add_caption('List of Parameters')

    for j, param in enumerate(paramsList):        
        with doc.create(Figure(position='H')) as plot:
            plot.add_image(os.path.join(HOME_FOLDER, param + '.pdf'))
            plot.add_caption(param)
            plot.append(Label('fig:param' + str(j)))

doc.generate_tex()
buildInfo = None

for _ in range(1):
        p = subprocess.Popen("pdflatex -synctex=1 -interaction=nonstopmode {} > LaTeX_Output.txt".format(texFileName), shell=True, bufsize=-1, 
                                stdout=subprocess.DEVNULL, cwd=None)
texFileName.replace('.tex', '.pdf')

My expected result is to have a clickable link in the table cell to the related parameter figure, i.e. Figure 1, instead I see the plain text i.e. Figure er{fig:param0}


Solution

  • OK, I solved this issue simply by using the dumps_as_content() method:

     with doc.create(Table(position='ht')) as table:
            with table.create(Center()) as centered:
                with centered.create(Tabular('|l|c|c|')) as tabular:
                    tabular.add_hline()
                    for j, param in enumerate(paramsList):
                        tabular.add_row('P' + str(j), param, NoEscape('Fig. ' + Ref('fig:param' + str(j)).dumps_as_content())))
                        tabular.add_hline()    
                table.add_caption('List of Parameters')