Skip to content

lucaslrodri/jupyter-tikz

Repository files navigation

Logo of Jupyter-TikZ

IPython Magics for rendering TeX/TikZ in Jupyter Notebooks

Read the Docs PyPI - Version Pypi - Downloads License

Documentation | Getting Started notebook

Installation

Prerequisites

Jupyter-TikZ is a Python (3.10+) and IPython Magics library. However, in order for Jupyter-TikZ to work properly, some non-Python dependencies need to be installed first:

  • LaTeX
  • latexmk
  • Poppler

LaTeX

LaTeX must be installed using one of the following distributions:

You can test if a LaTeX distribution is installed by using the following command:

pdflatex --version

latexmk

The default %%tikz / %tikz magic rendering path uses latexmk to compile TeX.

Check if latexmk is available:

latexmk -v

Poppler

This application requires Poppler's pdftocairo. You must install it beforehand.

Conda - Platform Independent

conda install -c conda-forge poppler

Windows

Download Poppler for Windows here. You must add the bin folder to your PATH.

Linux

Most distributions come with pdftocairo. If it is not installed, refer to your package manager to install poppler-utils.

Mac

Install using brew:

brew install poppler

Checking the Installation

Finally, you can check if the pdftocairo utility is installed by using the following command in your terminal:

pdftocairo -v

Using custom pdftocairo path

Alternatively, if you are facing issues, you can configure the pdftocairo location (exclusive for use in jupyter_tikz) by setting the environment variable JUPYTER_TIKZ_PDFTOCAIROPATH:

import os
custom_pdftocairo_path = os.path.join(
  os.getenv("LOCALAPPDATA"), "Poppler", "Library", "bin", "pdftocairo.exe"
)
os.environ["JUPYTER_TIKZ_PDFTOCAIROPATH"] = custom_pdftocairo_path

By default, executor-based rendering adds your current working directory to TeX's search path (TEXINPUTS). This allows relative inputs like \input{grid.tikz} and PGFPlots table {data.tsv} while still compiling in an isolated temporary directory. Set JUPYTER_TIKZ_DISABLE_CWD_TEXINPUTS=1 to opt out. -k/--keep-temp is for retaining build artifacts (debugging), not for enabling relative file loading.

Install Jupyter TikZ

You can install jupyter-tikz by using the following command in your terminal:

pip install jupyter-tikz

Adding TikZ Syntax highlight

If you are using Jupyter Lab 4. You can add LaTeX highlight to %%tikz magic cells by using JupyterLab-lsp and editing this part of the code in JupyterLab-lsp in the file extractor.ts:

new RegExpForeignCodeExtractor({
  language: 'latex',
  pattern: '^%%(latex|tikz)( .*?)?\n([^]*)', // Add tikz support to this line
  foreignCaptureGroups: [3],
  isStandalone: false,
  fileExtension: 'tex'
}),

Now, you will have LaTeX syntax code highlighting for %%tikz magic cells, as demonstrated below:

Using Jupyter TikZ with LaTeX syntax highlight

For more information refer to this link.

Basic usage

To begin, load the jupyter_tikz extension:

%load_ext jupyter_tikz

Use it as cell magic, it executes the TeX/TikZ code within the cell:

%%tikz
\begin{tikzpicture}
    \draw[help lines] grid (5, 5);
    \draw[fill=black!10] (1, 1) rectangle (2, 2);
    \draw[fill=black!10] (2, 1) rectangle (3, 2);
    \draw[fill=black!10] (3, 1) rectangle (4, 2);
    \draw[fill=black!10] (3, 2) rectangle (4, 3);
    \draw[fill=black!10] (2, 3) rectangle (3, 4);
\end{tikzpicture}

Conway example

Or use it as line magic, where the TeX/TikZ code is passed as an IPython string variable:

%tikz "$ipython_string_variable_with_code"

Additional options can be passed to the magic command:

%%tikz -i -t=pgfplots -nt -S=docs/assets/quadratic -r --dpi=150
\begin{axis}[
  xlabel=$x$,
  ylabel={$f(x) = x^2 + 4$}
]
    \addplot [red] {x^2 + 4};
\end{axis}

Quadratic formula

Going further, it is also possible to use it as a Python package:

from jupyter_tikz import TexFragment

tikz_code = tex_template_code = r"""\begin{tikzpicture}
    \draw[help lines] grid (5, 5);
     \filldraw [color=orange, opacity=0.3] (2.5,2.5) circle (1.5);
\end{tikzpicture}"""

tikz = TexFragment(tikz_code)  # Create the tex template object

tikz.run_latex()  # Run LaTeX and shows the output

Orange dot in a grid

Additional options

All additional options are listed below:

Argument Description
-as=<str>
--input-type=<str>
Type of the input. Possible values are: full-document, standalone-document and tikzpicture.
    Example: -as=full-document.
    Defaults to -as=standalone-document.
-i
--implicit-pic
Alias for -as=tikzpicture.
-f
--full-document
Alias for -as=full-document.
-p=<str>
--latex-preamble=<str>
LaTeX preamble to insert before the document.
    Example: -p "$preamble", with the preamble being an IPython variable.
    Defaults to None.
-t=<str>
--tex-packages=<str>
Comma-separated list of TeX packages.
    Example: -t=amsfonts,amsmath.
    Defaults to None.
-nt
--no-tikz
Force to not import the TikZ package.
-l=<str>
--tikz-libraries=<str>
Comma-separated list of TikZ libraries.
    Example: -l=calc,arrows.
    Defaults to None.
-lp=<str>
--pgfplots-libraries=<str>
Comma-separated list of pgfplots libraries.
    Example: -pl=groupplots,external.
    Defaults to None.
-nj
--no-jinja
Disable Jinja2 rendering.
-pj
--print-jinja
Print the rendered Jinja2 template.
-pt
--print-tex
Print the full LaTeX document.
-sc=<float>
--scale=<float>
The scale factor to apply to the TikZ diagram.
    Example: -sc=0.5.
    Defaults to -sc=1.0.
-r
--rasterize
Output a rasterized image (PNG) instead of SVG.
-d=<int>
--dpi=<int>
DPI to use when rasterizing the image.
    Example: --dpi=300.
    Defaults to -d=96.
-g
--gray
Set grayscale to the rasterized image.
-e
--full-err
Print the full error message when an error occurs.
-k[=<dir>]
--keep-temp[=<dir>]
Keep temporary files for debugging. Without a value, files are kept in the current directory; with a value, files are kept in the specified directory.
-os=<name>
--output-stem=<name>
Override artifact filename stem used by %tikz/%%tikz execution and kept temp files ([A-Za-z0-9][A-Za-z0-9._-]*).
-tc=<name>
--toolchain=<name>
Explicitly select executor toolchain.
    Example: --toolchain=xelatex_pdftocairo.
    Defaults to auto-resolution from --tex-program/environment.
-dg
--diagnose
Print toolchain diagnostics and skip rendering.
-j
--json
Use JSON diagnostics output. Must be combined with --diagnose; using --json alone returns an argument error. Legacy -json is still accepted.
-tp=<str>
--tex-program=<str>
TeX program to use for compilation.
    Example: -tp=xelatex or -tp=lualatex.
    Defaults to -tp=pdflatex.
-ta=<str>
--tex-args=<str>
Arguments to pass to the TeX program.
    Example: -ta "$tex_args_ipython_variable".
    Defaults to None.
-nc
--no-compile
Do not compile the TeX code.
-s=<str>
--save-tikz=<str>
Save the TikZ code to file.
    Example: -s filename.tikz.
    Defaults to None.
-st=<str>
--save-tex=<str>
Save full LaTeX code to file.
    Example: -st filename.tex.
    Defaults to None.
-sp=<str>
--save-pdf=<str>
Save PDF file.
    Example: -sp filename.pdf.
    Defaults to None.
-S=<str>
--save-image=<str>
Save the output image to file.
    Example: -S filename.png.
    Defaults to None.
-sv=<str>
--save-var=<str>
Save the TikZ or LaTeX code to an IPython variable.
    Example: -sv my_var.
    Defaults to None.

Contribute

Contributions are welcome from everyone! Whether you're reporting bugs, submitting feedback, or actively improving the codebase, your involvement is valuable. Here's how you can contribute:

  1. If you encounter any issues or have suggestions for improvements, please report them using the issues page.
  2. If you're interested in developing the software further, please refer to development guide.

Local quality commands

To run the same quality gates used by CI:

make ci-local

Or run step-by-step:

make fmt
make lint
make type
make test

Changelog

All notable changes to this project are presented below.

Migration notes (vs main)

  • artifacts_path is now directory-only in render_svg(...).
  • If you used artifacts_path as a filename prefix in main, migrate to artifacts_prefix.
  • %tikz --json now requires --diagnose. --json alone is rejected and rendering is skipped.
  • Output-path validation is stricter for user-provided paths. Relative .. path segments are rejected for --keep-temp, save targets, and JUPYTER_TIKZ_SAVEDIR-scoped writes.
  • Magic default routing changed for common engines. -tp=pdflatex and -tp=xelatex now run through the executor/toolchain path by default, which may change output details and dependency behavior.
  • Public validation now includes typed exceptions: InvalidToolchainError, InvalidOutputStemError, InvalidPathError (all are ValueError subclasses).
  • Toolchain/magic option precedence:
    1. --toolchain (explicit executor toolchain)
    2. --tex-program mapping (pdflatex/xelatex) when --tex-args is not set
    3. legacy path for other engines or custom --tex-args

Option precedence

If you provide... Selected rendering path
--toolchain=<name> Executor with that exact toolchain
no --toolchain, -tp=pdflatex, no --tex-args Executor pdftex_pdftocairo
no --toolchain, -tp=xelatex, no --tex-args Executor xelatex_pdftocairo
no --toolchain, -tp=lualatex Legacy TexDocument.run_latex
any --tex-args (without explicit --toolchain) Legacy TexDocument.run_latex

Migration cookbook (main -> current)

Common pattern in main Use now
render_svg(..., artifacts_path=\"out/demo\") (prefix-style path) render_svg(..., artifacts_prefix=\"out/demo\")
%tikz --json %tikz --diagnose --json (or %tikz -dg -j)
catching generic toolchain/path/stem ValueError only Optionally catch typed errors: InvalidToolchainError, InvalidPathError, InvalidOutputStemError
%tikz -tp=pdflatex expected legacy path behavior Expect executor default (pdftex_pdftocairo) unless you force legacy via custom --tex-args or other engine
relative .. in output targets (e.g. --keep-temp ../tmp) Use a local/safe path (e.g. --keep-temp outputs/tmp) or an absolute path

v0.5.8

✨ Improvements

  • Magic rendering now uses the executor/toolchain pipeline by default for pdflatex and xelatex.
  • Hardened legacy command execution by switching from shell command strings to argument-vector subprocess calls.
  • Improved executor result typing with a dataclass-based ExecutionResult API.
  • Standardized uncached-render failures to include the same stderr/log diagnostic tails as artifact-based failures.
  • Refactored monolithic jupyter_tikz.py into focused internal modules (args, models, magic, legacy_render) with backward-compatible facade exports.
  • Added default CWD TEXINPUTS injection so relative TeX inputs/PGFPlots tables work in temp-build mode (opt out with JUPYTER_TIKZ_DISABLE_CWD_TEXINPUTS=1).
  • Extended -k/--keep-temp to accept an optional output directory (e.g., -k=outputs/tmp) while preserving existing -k behavior.
  • Made artifact retention paths consistent: artifacts_path now means directory retention, and artifacts_prefix provides explicit prefix-based naming.
  • Added explicit --toolchain=<name> magic option with validation, and diagnostic reporting via --diagnose.

📚 Docs

  • Updated installation and troubleshooting guides to document latexmk and toolchain PATH requirements.
  • Added notes to the magic usage guide explaining --tex-program toolchain mapping and legacy fallback behavior.

v0.5.6

✨ Improvements

  • Docs: Added troubleshooting section to the Usage Guide.

v0.5.5

🐞 Bug Fixes

  • Removed quotation marks when using arg "$var" (e.g., -p "$preamble").

v0.5.4

🐞 Bug Fixes

  • Docs: Removed the Jinja2 subsection from the README.

v0.5.3

🐞 Bug Fixes

  • Docs: Fixed Jinja section in installation.

v0.5.2

🐞 Bug Fixes

  • Docs: Fixed internal links in index.

v0.5.1

🐞 Bug Fixes

  • Docs: Minor fix in changelog.

v0.5.0

🚨 Breaking Changes

  • Significant changes to Jinja2 rendering:
    • Replaced the default Jinja2 syntax with a custom one to avoid clashes with LaTeX braces ({}). Please refer to the documentation for more details.
    • With the new syntax, conflicts with LaTeX are significantly reduced, thus Jinja2 is now enabled by default and has become a mandatory dependency.
    • Added a --no-jinja flag to allow optional disabling of Jinja2 rendering.

v0.4.2

🐞 Bug Fixes

  • Doc: Fixed social cards image links.

v0.4.1

✨ Improvements

  • Switched temporary file names to MD5 hashing for deterministic hashes.

🚀 Features

  • Doc: Support to social cards (Twitter and Facebook OG).

🐞 Bug Fixes

  • Fixed indentation in TexDocument.tikz_code.
  • Fixed docs issues.

v0.4.0

🚀 Features

  • Added support for PGFPlots with external data files.
  • Introduced a new flag (-k) to retain LaTeX temporary files.
  • Added support for grayscale output in rasterized mode.
  • Introduced new flags --save-tikz and --save-pdf to save the TikZ and PDF files respectively; --save-tex now explicitly saves the full LaTeX document.

🚨 Breaking Changes

  • Modified the save functionality: Options must now be passed in TexDocument.run_latex(...) as TexDocument.save() is no longer used.
  • LaTeX rendering is now performed in the current folder, moving away from the use of a temporary directory (tempdir). This change facilitates access to external files for PGFPlots.

v0.3.2

🐞 Bug Fixes

  • Improved documentation visibility on mobile devices.

v0.3.1

🐞 Bug Fixes

  • Fixed DOCs links.

v0.3.0

🚀 Features

  • Web documentation.
  • Flag (--print-tex) to print the full LaTeX document.
  • UTF-8 support.
  • Added support for Python 3.10.

🚨 Breaking Changes

  • Replaced --full-document and --implicit-pic with --input-type=<str>. -f and -i still working as aliases.
  • Changed the --as-jinja flag to --use-jinja.
  • Reworked the API to an object-oriented approach.

v0.2.1

🐞 Bug Fixes

  • Minor adjustments in the README and Getting Started Notebook.

v0.2.0

🚀 Features

  • Option to save output code to an IPython variable (-sv=<var_name>).
  • Flag (--no-compile) to prevent LaTeX compilation and image rendering.
  • Support for LaTeX \input{...} commands.

v0.1.1

🐞 Bug Fixes

  • Minor fixes in README.

🚀 Features

  • Added PyPI badge.

v0.1.0

  • First version released on PyPI.

Thanks

I had been using ITikZ for years. However, it doesn't update often and relies on the outdated pdf2svg for converting PDFs to images, which causes problems in Windows environments. Inspired by ITikZ and IPython TikZ Magic, I decided to create my own package, adding new features such as support for preambles, new Jinja syntax, and the ability to save the LaTeX result to IPython variables. I also switched from pdf2svg to Poppler, which works perfectly on all plataforms, including Windows.

License

Copyright 2024 © Lucas Lima Rodrigues.

Distributed under the terms of the MIT License, Jupyter-TikZ is free and open-source software.

About

IPython Magics for rendering TeX/TikZ in Jupyter Notebooks

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors