Create beamer slides using Python

Utpal Kumar   3 minute read      

I had several figures for my research purpose, and I wanted to include those figures in my report. I had two options: I should add each picture manually using Microsoft Powerpoint, Google Slides, or use latex or find some way to compile them together to create a presentation automatically. The first way is more flexible as it allows me to add more details to each slide. But it requires manually including all the figures. It can quickly become tedious job when I have, say, 50 figures. I need a programmatic way to compile all the figures together and still have some flexibility to add details to each slide.

After some research through Google search, I came across a Python package called Pylatex.

The one mental model

PyLaTeX writes LaTeX for you. You build a document object in Python — here with documentclass="beamer" — appending sections, itemize lists, and figures, then call generate_pdf(...), which runs pdflatex to produce the slides. The win: loop over your figures and emit one slide per figure automatically, instead of pasting 50 images by hand.

Auto-generating Beamer slides with PyLaTeX Figures and event info are looped into a PyLaTeX Beamer document, one slide per figure, then generate_pdf runs pdflatex to produce the PDF slides. Figures + data PNGs, event info PyLaTeX document beamer · one slide / figure generate_pdf runs pdflatex PDF slides event_based_analysis.pdf
PyLaTeX assembles the Beamer source in Python; pdflatex turns it into the finished slide deck.

Example script to create a beamer slide

This is the example script for creating a beamer slide. One can modify or learn from this script to build the slides according to ones’ need.

import numpy as np
import os, glob
from pylatex import Document, Section, Subsection, Tabular, Command
from pylatex import Math, TikZ, Axis, Plot, Figure, Matrix, Alignat
from pylatex import PageStyle, Head, Foot, MiniPage, \
    StandAloneGraphic, MultiColumn, Tabu, LongTabu, LargeText, MediumText, \
    LineBreak, NewPage, Tabularx, TextColor, simple_page_number, Itemize, Hyperref, Package
from pylatex.utils import italic, bold, NoEscape, escape_latex
import os
import pandas as pd


def hyperlink(url,text):
    text = escape_latex(text)
    return NoEscape(r'\href{' + url + '}{' + text + '}')

event_info_dir = 'events_station_info'
all_station_info_files = glob.glob(f"{event_info_dir}/*.txt")
event_maps_dir = 'events_station_maps'

if __name__ == '__main__':

    geometry_options = {"tmargin": "1cm", "lmargin": "1cm", "margin": "1cm"}
    doc = Document(geometry_options=geometry_options, 
            documentclass="beamer",
            )
    doc.packages.append(Package('hyperref'))
    
    with doc.create(Section('Titlepage')):
        doc.preamble.append(Command('title', 'Preliminary Waveform Data Selection'))
        doc.preamble.append(Command('author', 'Utpal Kumar'))
        doc.preamble.append(Command('date', NoEscape(r'\today')))
        doc.append(NoEscape(r'\maketitle'))

    totstationslist = []
    for ff in glob.glob(f"{event_maps_dir}/*.png"):
        numstation = int(os.path.basename(ff).split('.png')[0].split("_")[-1])
        totstationslist.append(numstation)
    totstationsinds = np.argsort(totstationslist)
    totstationsinds = totstationsinds[::-1] #reverse order

    for ind in totstationsinds:
        ff = all_station_info_files[ind]
        dff_events = pd.read_csv(ff, nrows=1)
        evname = dff_events.loc[0,'eventorig']
        eventbrk = dff_events.loc[0,'eventbrk']
        # print(evname)
        station_map_file_list = glob.glob(f"{event_maps_dir}/*{evname}_*.png")
        if len(station_map_file_list):
            station_map_file = station_map_file_list[0]
            print(station_map_file)
            with doc.create(Section('Slide')):
                with doc.create(Itemize()) as itemize:
                    itemize.add_item(f"{evname}, Dep: {dff_events.loc[0,'eventdepth']}, Mag: {dff_events.loc[0,'eventmag']}")
                with doc.create(Subsection('Figure')):
                    with doc.create(Figure(position='h!')) as fig_map:
                        fig_map.add_image(station_map_file, width='230px')
                        fig_map.add_caption(f'Station Map for {evname}')

                doc.append(NewPage())

	# Creating a pdf
    doc.generate_pdf('event_based_analysis', clean_tex=False, clean=True)

Reading it top to bottom: the script sets up a beamer Document, adds a title page in the preamble, then sorts the events by station count and loops over them — for each event it opens a new Section (“slide”), adds an Itemize bullet with the event’s depth and magnitude, embeds the matching station-map figure, and starts a NewPage. Finally, generate_pdf(..., clean_tex=False) compiles everything and keeps the intermediate .tex so you can tweak it further.

You need LaTeX installed. generate_pdf shells out to pdflatex, so a LaTeX distribution (e.g. TeX Live or MacTeX) must be on your PATH. Install PyLaTeX itself with pip install pylatex. (Only a handful of the imports above — Document, Section, Subsection, Itemize, Figure, Command, Package, NoEscape — are actually used here; the rest are handy for richer documents.)

Check your understanding

What makes this script produce a *slide deck* rather than an article PDF?

<button class="ei-quiz__option" data-correct="true" data-feedback="documentclass=\"beamer\" tells LaTeX to use the Beamer class, which renders each section/frame as a slide.">Setting documentclass="beamer" on the Document</button>

Recap

Without scrolling up — what’s the workflow?

  • PyLaTeX builds a LaTeX document in Python with documentclass="beamer".
  • You loop over your figures/data, emitting one Section (slide) each with a bullet and an image.
  • generate_pdf runs pdflatex to compile the deck (needs a LaTeX install).
  • The result: 50 figures become 50 slides automatically — reproducibly and re-runnable.

Where to go next

Disclaimer of liability

The information provided by the Earth Inversion is made available for educational purposes only.

Whilst we endeavor to keep the information up-to-date and correct. Earth Inversion makes no representations or warranties of any kind, express or implied about the completeness, accuracy, reliability, suitability or availability with respect to the website or the information, products, services or related graphics content on the website for any purpose.

UNDER NO CIRCUMSTANCE SHALL WE HAVE ANY LIABILITY TO YOU FOR ANY LOSS OR DAMAGE OF ANY KIND INCURRED AS A RESULT OF THE USE OF THE SITE OR RELIANCE ON ANY INFORMATION PROVIDED ON THE SITE. ANY RELIANCE YOU PLACED ON SUCH MATERIAL IS THEREFORE STRICTLY AT YOUR OWN RISK.


Leave a comment