0

(Using Python 3.6.1 on Win10, in a virtualenv that basically just has numpy/pandas/matplotlib installed, for number-crunching stuff. I don't have Tkinter installed and would prefer to keep it that way.)

I have the following test code, attempting to render MathML text statically:

import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plot


def render(mathml):
    plot.clf()
    plot.rc('font', family='monospace', size=72)
    plot.axis('off')
    plot.text(0, 0, f'{mathml}')
    plot.savefig(f'hax.png')


render('$lorem^{ipsum}$')

The resulting test.png shows the text in the default font (DejaVu Sans Oblique), not in a monospace font:

improperly rendered text

Explicitly specifying a font (e.g. family='Courier New') also has no effect, and neither does changing the output format. The text is properly resized, and no error or warning appears - the output just doesn't show the right font.

What's going on here? How can I fix it?

2
  • I don't have Tkinter installed and would prefer to keep it that way, tkinter is already apart of the Python Standard Library, so its already installed. Commented Apr 17, 2020 at 6:49
  • It is entirely possible with the Windows standard installer to omit it (along with IDLE). Commented Apr 18, 2020 at 1:28

1 Answer 1

5

Options for math fonts are according to the tutorial

DejaVu Sans (default), DejaVu Serif, the Computer Modern fonts (from (La)TeX), STIX fonts (with are designed to blend well with Times), or a Unicode font that you provide

Sticking with the default, you can get a "typewriter"-like feeling using \mathtt

import matplotlib.pyplot as plt


def render(mathml):
    plt.clf()
    plt.rc('font', size=72)
    plt.axis('off')
    plt.text(0, 0, f'$\\mathtt{{{mathml}}}$')
    plt.show()

render('lorem^{ipsum}')

enter image description here

To use at custom fontset for mathtext is possible via the mathtext.fontset rc parameter.

plt.rcParams["mathtext.fontset"] = "custom"

For courier new font, this could look like

import matplotlib.pyplot as plt

def render(mathml):
    plt.clf()
    plt.rc('font', size=72)
    plt.rc('mathtext', fontset="custom", tt="Courier New")
    plt.axis('off')
    plt.text(0, 0, f'$\\mathtt{{{mathml}}}$')
    plt.show()

render('lorem^{ipsum}')

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

It hadn't even occurred to me that a separate method might be needed to choose a font for MathML text vs. ordinary text. I tested the original code with a plain 'lorem ipsum' string and it did work. Trying this approach, at first I got an error that \mathtt{ is an unknown symbol. This was misleading - I had forgotten to strip the $ from the test input, so presumably the rendering engine just saw $\mathtt{$ followed by garbage. Working beautifully now. Thanks :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.