LaTeX commands not working with LaTeXStrings eg \mathfrak, \boldsymbol

Hello,

Some routines like \boldsymbol or \mathfrak don’t work for me with LaTeXStrings, while some others like \mathsf or \mathrm do. Is it due to my setup, or is it a limitation of LaTeXStrings? Do you know how to fix this issue?

using Plots
pyplot()
using LaTexStrings
plot(randn(10), xlabel = L"\mathfrak{x}")

The output

PyError ($(Expr(:escape, :(ccall(#= /home/mat/.julia/packages/PyCall/BD546/src/pyfncall.jl:43 =# @pysym(:PyObject_Call), PyPtr, (PyPtr, PyPtr, PyPtr), o, pyargsptr, kw))))) <class 'RuntimeError'>
RuntimeError("latex was not able to process the following string:\nb'$\\\\\\\\mathfrak{x}$'\n\nHere is the full report generated by latex:\nThis is pdfTeX, Version 3.14159265-2.6-1.40.20 (TeX Live 2019/Debian) (preloaded format=latex)\n restricted \\write18 enabled.\nentering extended mode\n(/home/mat/.cache/matplotlib/tex.cache/e8fc45a917ccae9fdfc2995fec447793.tex\nLaTeX2e <2020-02-02> patch level 2\nL3 programming layer <2020-02-14>\n(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls\nDocument Class: article 2019/12/20 v1.4l Standard LaTeX document class\n(/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo))\n(/usr/share/texlive/texmf-dist/tex/latex/type1cm/type1cm.sty)\n(/usr/share/texmf/tex/latex/cm-super/type1ec.sty\n(/usr/share/texlive/texmf-dist/tex/latex/base/t1cmr.fd))\n(/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty)\n(/usr/share/texlive/texmf-dist/tex/latex/geometry/geometry.sty\n(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty)\n(/usr/share/texlive/texmf-dist/tex/generic/iftex/ifvtex.sty\n(/usr/share/texlive/texmf-dist/tex/generic/iftex/iftex.sty)))\n(/usr/share/texlive/texmf-dist/tex/latex/base/textcomp.sty)\n(/usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-dvips.def)\nNo file e8fc45a917ccae9fdfc2995fec447793.aux.\n*geometry* driver: auto-detecting\n*geometry* detected driver: dvips\n! Undefined control sequence.\n<recently read> \\mathfrak \n                          \nl.19 {\\rmfamily $\\mathfrak\n                          {x}$}\nNo pages of output.\nTranscript written on e8fc45a917ccae9fdfc2995fec447793.log.\n\n\n")
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/artist.py", line 74, in draw_wrapper
    result = draw(artist, renderer, *args, **kwargs)
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/figure.py", line 2780, in draw
    mimage._draw_list_compositing_images(
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/image.py", line 132, in _draw_list_compositing_images
    a.draw(renderer)
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/_api/deprecation.py", line 431, in wrapper
    return func(*inner_args, **inner_kwargs)
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/axes/_base.py", line 2921, in draw
    mimage._draw_list_compositing_images(renderer, self, artists)
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/image.py", line 132, in _draw_list_compositing_images
    a.draw(renderer)
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/axis.py", line 1150, in draw
    self.label.draw(renderer)
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/artist.py", line 51, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/text.py", line 679, in draw
    bbox, info, descent = textobj._get_layout(renderer)
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/text.py", line 314, in _get_layout
    w, h, d = renderer.get_text_width_height_descent(
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/backends/backend_agg.py", line 229, in get_text_width_height_descent
    w, h, d = texmanager.get_text_width_height_descent(
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/texmanager.py", line 399, in get_text_width_height_descent
    dvifile = self.make_dvi(tex, fontsize)
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/texmanager.py", line 291, in make_dvi
    self._run_checked_subprocess(
  File "/home/mat/.julia/conda/3/lib/python3.9/site-packages/matplotlib/texmanager.py", line 260, in _run_checked_subprocess
    raise RuntimeError(


Stacktrace:
  [1] pyerr_check
    @ ~/.julia/packages/PyCall/BD546/src/exception.jl:62 [inlined]
  [2] pyerr_check
    @ ~/.julia/packages/PyCall/BD546/src/exception.jl:66 [inlined]
  [3] _handle_error(msg::String)
    @ PyCall ~/.julia/packages/PyCall/BD546/src/exception.jl:83
  [4] macro expansion
    @ ~/.julia/packages/PyCall/BD546/src/exception.jl:97 [inlined]
  [5] #107
    @ ~/.julia/packages/PyCall/BD546/src/pyfncall.jl:43 [inlined]
  [6] disable_sigint
    @ ./c.jl:458 [inlined]
  [7] __pycall!
    @ ~/.julia/packages/PyCall/BD546/src/pyfncall.jl:42 [inlined]
  [8] _pycall!(ret::PyCall.PyObject, o::PyCall.PyObject, args::Tuple{PyCall.PyObject}, nargs::Int64, kw::Ptr{Nothing})
    @ PyCall ~/.julia/packages/PyCall/BD546/src/pyfncall.jl:29
  [9] _pycall!(ret::PyCall.PyObject, o::PyCall.PyObject, args::Tuple{PyCall.PyObject}, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ PyCall ~/.julia/packages/PyCall/BD546/src/pyfncall.jl:11
 [10] (::PyCall.PyObject)(::PyCall.PyObject, ::Vararg{PyCall.PyObject, N} where N; kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ PyCall ~/.julia/packages/PyCall/BD546/src/pyfncall.jl:86
 [11] (::PyCall.PyObject)(::PyCall.PyObject, ::Vararg{PyCall.PyObject, N} where N)
    @ PyCall ~/.julia/packages/PyCall/BD546/src/pyfncall.jl:86
 [12] py_drawfig(fig::PyPlot.Figure)
    @ Plots ~/.julia/packages/Plots/S30zV/src/backends/pyplot.jl:271
 [13] _before_layout_calcs(plt::Plots.Plot{Plots.PyPlotBackend})
    @ Plots ~/.julia/packages/Plots/S30zV/src/backends/pyplot.jl:1387
 [14] prepare_output(plt::Plots.Plot{Plots.PyPlotBackend})
    @ Plots ~/.julia/packages/Plots/S30zV/src/plot.jl:217
 [15] show(io::Base64.Base64EncodePipe, m::MIME{Symbol("image/png")}, plt::Plots.Plot{Plots.PyPlotBackend})
    @ Plots ~/.julia/packages/Plots/S30zV/src/output.jl:212
 [16] base64encode(::Function, ::MIME{Symbol("image/png")}, ::Vararg{Any, N} where N; context::Nothing)
    @ Base64 /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/Base64/src/encode.jl:209
 [17] base64encode
    @ /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.6/Base64/src/encode.jl:206 [inlined]
 [18] _ijulia_display_dict(plt::Plots.Plot{Plots.PyPlotBackend})
    @ Plots ~/.julia/packages/Plots/S30zV/src/ijulia.jl:44
 [19] display_dict(plt::Plots.Plot{Plots.PyPlotBackend})
    @ Plots ~/.julia/packages/Plots/S30zV/src/init.jl:93
 [20] #invokelatest#2
    @ ./essentials.jl:708 [inlined]
 [21] invokelatest
    @ ./essentials.jl:706 [inlined]
 [22] execute_request(socket::ZMQ.Socket, msg::IJulia.Msg)
    @ IJulia ~/.julia/packages/IJulia/e8kqU/src/execute_request.jl:112
 [23] #invokelatest#2
    @ ./essentials.jl:708 [inlined]
 [24] invokelatest
    @ ./essentials.jl:706 [inlined]
 [25] eventloop(socket::ZMQ.Socket)
    @ IJulia ~/.julia/packages/IJulia/e8kqU/src/eventloop.jl:8
 [26] (::IJulia.var"#15#18")()
    @ IJulia ./task.jl:411

First, realize that the LaTeXStrings package does not do any LaTeX rendering — it’s simply a way of entering strings of LaTeX math without lots of escapes. The actually rendering is done by the plotting backend, which in your example is Matplotlib (via PyPlot.jl). Matplotlib, in turn, uses its own LaTeX math renderer. Some other Plots.jl backends use mathjax, some use MathTeXEngine.jl, and yet other plotting backends don’t support LaTeX math at all.

Typically, the most you can hope for that these backends render standard LaTeX math macros. The \mathfrak macro, however, is not standard LaTeX — it is provided by the amsfonts package. Similarly, \boldsymbol is provided by amsbsy (included by amsmath).

(If you want, it is possible to get Matplotlib to use a full LaTeX renderer, assuming you have it installed, in which case you can use arbitrary LaTeX packages if you configure things correctly.)

8 Likes

Wow! I’d like to know how to configure the renderer of Makie. There, \text macro is not available, which is annoying.

File an issue with GitHub - Kolaru/MathTeXEngine.jl: A latex math mode engine in pure Julia., which Makie’s math renderer. It supports \mathrm, though, which is maybe what you want? (Add basic support for font command and add convenience access to fonts by Kolaru · Pull Request #27 · Kolaru/MathTeXEngine.jl · GitHub)

1 Like