ANN: TeXLayout.jl - typeset your LaTeX in Makie

I’ve been working on (another) pure-Julia LaTeX typesetting package TeXLayout.jl that is focused on rendering nice mathematics in Makie.jl (mostly CairoMakie.jl) for various diagramming needs that I have (lecture notes…).

One example of the sort of things it can do is:

Note I’ve only just tagged this version (v0.2), so it might take a little while to propagate through the package server.

Key features are:

  • Any OpenType Math font can be used; the placement metrics are taken from the MATH table in the font. In principle, this means that quite a wide range of fonts are available, though your mileage may vary since some math fonts are better than others. (Above is an example of the Luciole font.)
  • Mixed text / maths is supported. I’m predominantly targeting maths support, but there is basic text as well (nothing that requires iterative layouts though, so no automatic line breaking or things like that). This means you can use multi-line equations embedded in text, or inline mathematics. (I’ve designed it so I can include HarfBuzz-based typography later as an optional extension, but I haven’t got that far yet.)
  • Good coverage of LaTeX mathematics. There is always more to add, but I think I’ve got most things that people will use.
  • I’ve paid a bit of attention to performance. Whilst plotting diagrams isn’t usually a time critical thing, I don’t like wasting CPU cycles unnecessarily.

There are a few alternative packages available, just to highlight some differences:

  • MathTeXEngine.jl is also pure Julia and is much more battle tested. However, it is more limited on the fonts available (placement metrics are hardcoded). It doesn’t handle matrices and is generally a bit more limited on the mathematics. It also doesn’t handle general text / multi-line equations.
  • MakieTeX.jl is a wrapper around a LaTeX installation. It is much more versatile in terms of the LaTeX it can handle since it uses LaTeX directly, but it’s a much heavier solution.

At the moment, the Makie integration relies on some type piracy; hopefully a solution will be available in the future to mean that isn’t needed.

Comments / questions / issues all welcome.

Very nice! We consider using it in MakieControlPlots.jl.

Question:
What is a good way to achieve consistant fonts for labels that do not use LaTeX and those that do?

Or do I have to use the L prefix for all labels, titels etc to achieve consistant fonts?

I’ve got an example of that in the README - you can set the Makie theme and TeXLayout to use the same font set:

using TeXLayout, CairoMakie, LaTeXStrings

# you can change the default font with, e.g., set_default_font_family!(:fira_math)
ff = default_font_family()   # whichever family is currently active in TeXLayout

set_theme!(fonts = (;
    regular    = ff.regular,
    bold       = ff.bold,
    italic     = ff.italic,
    bolditalic = ff.bolditalic,
))  # set the theme in Makie

fig = Figure(size = (800, 500))
ax  = Axis(fig[1, 1]; xlabel = L"x", ylabel = L"f(x)")
x   = LinRange(0, 2π, 400)
lines!(ax, x, sin.(x); label = L"\sin(x)")
lines!(ax, x, exp.(-x/4).*sin.(3x); label = L"e^{-x/4}\sin(3x)")
axislegend(ax)
save("output.png", fig)

This was one of my design goals - I’m very keen on font consistency!

Can the use of this package with CairoMakie be shown on the documentation page for CairoMakie? This package addressed the only fly in the ointment for me, CairoMakie-wise.

That’s not one for me - I don’t have any connection with the Makie folks. You could try opening an issue there?

There is some work in progress on trying to make the text backends a bit more customisable / changeable in Makie, but I don’t know how quickly that is developing.

Hi, is there a way to use TeXLayout.jl to use the small caps version of a font?

I tried different versions of:

using TeXLayout
set_default_font_family!(:termes)

using CairoMakie

fig = Figure()
ax = Axis(
    fig[1, 1],
    title=L"\text{\textsc{This text should be in small caps}}",
    xlabel="X-axis",
    ylabel="Y-axis",
)
lines!(ax, 1:10, rand(10))
display(fig)

but without success…

Thanks!

Not yet, but I’ll take a look because that would be useful.

Thanks!

This should now work on the main branch (I’ll cut a new release later today, hopefully; EDIT: now released as v0.2.3).

Because of how the OpenType fonts work, this is harder than I initially thought. Fortunately, I already implemented (read: Claude implemented) HarfBuzz support a few weeks ago, which does this nicely. However, it does mean that you need a dependency on HarfBuzz to get small caps (but you do get nicer typeset text in return, with ligatures and proper kerning, etc).

To run your example you need

using TeXLayout, HarfBuzz_jll

set_default_font_family!(:termes)
set_default_layout_options!(shaper = HarfBuzzShaper())

using CairoMakie

fig = Figure()
ax = Axis(
    fig[1, 1],
    title=L"\text{\textsc{This text should be in small caps}}",
    xlabel="X-axis",
    ylabel="Y-axis",
)
lines!(ax, 1:10, rand(10))
display(fig)

Thank you very much for the quick update!

It works perfectly indeed. Now if it’s not too much to ask, I’d also like to switch between font families. This is already possible using rich text but to my knowledge not for Latex strings unfortunately. Something like:

using TeXLayout, HarfBuzz_jll

set_default_font_family!(:termes)
set_default_layout_options!(shaper = HarfBuzzShaper())

using CairoMakie

fig = Figure()
ax = Axis(
    fig[1, 1],
    title=L"\text{\textsc{Small caps} and \textsf{sans serif font} and \textsc{\textsf{both combined!}} }",
    xlabel="X-axis",
    ylabel="Y-axis",
)
lines!(ax, 1:10, rand(10))
display(fig)

That should all work on main (v0.3.0 is currently going through registrator and will be available shortly). As a bonus, you get typewriter (monospace) fonts as well.

It currently defaults to TeX Gyre Heros / Cursor but that can be customised (see example in the docs).

BTW: you can use latexstring(raw"\textsc{Small caps} and \textsf{sans serif font} and \textsc{\textsf{both combined!}}") rather than having to wrap everything inside \text when using L"...". (See this example.)

That’s amazing! I can finally get a perfect consistency between my LaTeX document and the figures. Thank you very much!

Just a quick update: I don’t know if it’s a bug but I haven’t been able to type a percentage sign within a latex string even by escaping it. It just doesn’t display.

Thanks for letting me know - that got missed in a previous iteration. Now fixed on main and will be released in v0.3.1 shortly.