Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Python API

You can use gtdraw as a Python library to generate game trees programmatically. When working in a Jupyter Notebook, you should use the draw function to display the game tree directly in the notebook output:

from gtdraw import draw
draw('games/example.ef')

To generate other output formats, use the tex, pdf, png, and svg functions, all of which (including draw above) accept the same keyword arguments (see below).

Example usage:

from gtdraw import tex, pdf, png, svg

pdf(
    "game.ef",
    font_family="sffamily",
    font_bold=True,
    font_size="large",
    horizontal=True,
)
svg(
    "game.efg",
    color_scheme="custom",
    custom_colors={0: "#FF0000", 1: "#0000FF"},
    iset_fill=True,
    iset_fill_opacity=0.3,
)
png(
    "game.ef",
    iset_boundary="dotted",
    node_size=2.0,
)

API Keyword Arguments

All output format functions (draw, tikz, tex, pdf, png, svg) accept a variety of keyword arguments to customize the output.

CategoryArgumentDescription
Formattingsave_to="filename"Specify output filename (with or without extension).
dpi=XSet PNG resolution in DPI for png (72-2400, default: 300).
responsive_sizing=True/FalseMake SVG output responsive for svg (default: False).
Layoutscale_factor=X.XSet scale factor (0.01 to 100, default: 1.0).
horizontal=True/FalseSwitch from vertical to horizontal layout (default: False).
mirror=True/FalseMirror the tree left-to-right by flipping xshift values (default: False).
legend_position="X"Corner for the colour legend: "top-left" (default), "top-right", "bottom-left", "bottom-right".
action_label_dist=X.XDistance of action labels from the edge (default: 1.0).
action_label_position=XPosition of action labels along the edge. Accepts a single float (0.0 to 1.0, default: 0.5), a dictionary keyed by player index (e.g. {0: 0.3, 1: 0.7}), or a dictionary keyed by level index (e.g. {0: 0.3, 1: 0.6}).
action_label_position_by=\"X\"Interpret a dictionary action_label_position as keyed by player index ("player", default) or by tree level index ("level").
vary_action_label_positions=True/FalseVary action label positions along child edges of a node to avoid clashes (default: False).
vary_action_label_positions_by=\"X\"Apply vary logic to "all" nodes (default), or selectively to specific "player" or "level" indices.
vary_action_label_positions_choices=[...]List of player or level indices to apply vary logic to (used with vary_action_label_positions_by="player" or "level"). None means all (default).
level_scaling=X.XLevel spacing multiplier (for pygambit, default: 1.0).
sublevel_scaling=X.XSublevel spacing multiplier (for pygambit, default: 1.0).
width_scaling=X.XWidth spacing multiplier (for pygambit, default: 1.0).
shared_terminal_depth=True/FalseEnforce shared terminal node depth (for pygambit, default: False).
Information Setsiset_fill=True/FalseFill information sets with player colors (default: False).
iset_fill_opacity=X.XOpacity of information set fill (0.0-1.0, default: 0.2).
iset_boundary="X"Boundary style: "solid", "dotted", "none" (default: "solid").
Label Backgroundlabel_bg=True/FalseAdd a filled background behind all label text to improve readability. Also accepts a dict[int, bool] to enable per-player or per-level (use with label_bg_by, default: False).
label_bg_by="X"Interpret a dictionary label_bg as keyed by player index ("player", default) or by tree level index ("level").
label_bg_style="X"Background style: "player_bg" (player-colour background with white text, default) or "white_bg" (white background with player-colour text).
label_bg_color="X"Fallback colour of the label background when no player colour applies. Accepts any named xcolor colour (e.g. "white") or a hex string (e.g. "#ffcc00") (default: "white").
label_bg_opacity=X.XOpacity of the label background (0.0-1.0, default: 0.8).
Aestheticscolor_scheme="X"Set color scheme ("default", "gambit", "distinctipy", "colorblind", "custom").
edge_thickness=X.XSet thickness of edges (default: 1.0).
font_family="X"Set the global LaTeX font family ("rmfamily", "sffamily", "ttfamily").
font_size="X"Set the LaTeX font size command ("small", "normalsize", "large", "Large").
font_bold=True/False, font_italic=True/FalseUse bold or italic text for labels and payoffs.
custom_colors={0: "#HEX",...}Map player indices (0=chance) to hex colors.
node_size=X.XSize of player nodes in mm (default: 1.5).
show_grid=True/FalseShow helper grid in the background (default: False).

Interoperability with pygambit

gtdraw supports pygambit game objects directly. Check out the pygambit documentation which contains tutorials that use gtdraw to render game trees. In particular, read Tutorial 4) Creating publication-ready game images.

You can pass a pygambit game object to the drawing functions:

import pygambit as gbt
from gtdraw import draw, tex, pdf, png, svg

g = gbt.read_efg('somegame.efg')
draw(g)
tex(g)
pdf(g)
png(g)
svg(g)

Or pass the path to an .efg file directly:

from gtdraw import pdf
pdf('somegame.efg')

Format Conversion

gtdraw provides two functions for converting between .ef and .efg file formats:

from gtdraw import ef_to_efg, efg_to_ef

# Convert EF to Gambit EFG
ef_to_efg("game.ef")
ef_to_efg("game.ef", save_to="output.efg", title="My Game")

# Convert EFG to EF (requires pygambit)
efg_to_ef("game.efg")
efg_to_ef("game.efg", save_to="output.ef", level_scaling=1.5)

# You can also pass a pygambit Game object
import pygambit as gbt
g = gbt.read_efg("game.efg")
efg_to_ef(g, save_to="output.ef")

Conversion Arguments

FunctionArgumentDescription
ef_to_efggamePath to the .ef file (required).
save_to="filename"Output filename. Defaults to the input filename with .efg extension.
title="My Game"Title string for the EFG prologue. Defaults to the input filename stem.
efg_to_efgamePath to the .efg file, or a pygambit.gambit.Game object (required).
save_to="filename"Output filename. Defaults to the game title with .ef extension.
level_scaling=X.XLevel spacing multiplier (default: 1.0).
sublevel_scaling=X.XSublevel spacing multiplier (default: 1.0).
width_scaling=X.XWidth spacing multiplier (default: 1.0).
shared_terminal_depth=True/FalseEnforce shared terminal node depth (default: False).

Both functions return the path to the generated output file.

Normal Form Games (NFG)

gtdraw also supports normal form (strategic form) games via pygambit:

import pygambit as gbt
from gtdraw import draw, tex, pdf, png, svg

# From a pygambit NFG object
g = gbt.read_nfg("games/nfg/example.nfg")
draw(g)       # returns \begin{game}...\end{game} body; displays image in Jupyter
pdf(g)    # compiles payoff table to PDF
png(g)    # compiles payoff table to PNG
svg(g)    # compiles payoff table to SVG

# Or directly from the .nfg file path
pdf("games/nfg/example.nfg", save_to="battle_of_sexes.pdf")

tikz() on an NFG returns the raw \begin{game}...\end{game} LaTeX body (not TikZ code). PDF/PNG/SVG compilation requires pdflatex and the sgame LaTeX package (texlive-games on Ubuntu).

Tree-specific keyword arguments (horizontal, mirror, iset_fill, scale_factor, etc.) are accepted but silently ignored for NFG inputs.