Search code examples
matplotlibsvgblender

Using mathtext parser to output a svg file


Context

I'm looking for a simple way to import properly typeset mathematics (with LaTeX) into blender. A solution for this has already been given. But that means getting out of blender, using multiple tools and then going back to blender and importing the whole thing.

Blender comes with Python and can import svg

I'd like to find an other way and blender has a set of powerful tools based on Python. I was thinking: can I make Python parse some TeX input and then generate a svg (virtual) file inside blender. That would solve the problem.

matplotlib "emulates" TeX

It is possible to install any Python library and use it inside blender. So this made me think of a possible "hack" of matplotlib.

mathtext is a module that provides a parser for strings with TeX-like syntax for mathematical expressions. svg is one of the available "backends".

Consider the following snippet.

import matplotlib.mathtext as mathtext

parser = mathtext.MathTextParser('svg')
 
t = parser.parse(r'$\int_{0}^{t} x^2 dx = \frac{t^3}{3}$')

t is a tuple that has all the information needed. But I can't find a way (in the backend api) to convert it to a (virtual) svg file.

Any ideas?

Thanks


Solution

  • Matplotlib needs a figure (and currently also a canvas) to actually be able to render anything. So in order to produce an svg file whose only content is a text (a mathtext formula) you still need a figure and a canvas and the text needs to actually reside inside the figure, which can be achieved by fig.text(..). Then you can save the figure to svg via fig.savefig(..). Using the bbox_inches="tight" option ensures the figure to be clipped to the extent of the text. And setting the facecolor to a transparent color removes the figure's background patch.

    from matplotlib.backends.backend_agg import FigureCanvasAgg
    from matplotlib.figure import Figure
    
    fig = Figure(figsize=(5, 4), dpi=100)
    canvas = FigureCanvasAgg(fig)
    
    fig.text(.5, .5, r'$\int_{0}^{t} x^2 dx = \frac{t^3}{3}$', fontsize=40)
    fig.savefig("output.svg", bbox_inches="tight", facecolor=(1,1,1,0))
    

    enter image description here