23

I have the following lines to render TeX annotations in my matplotlib plot:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc

rc('text', usetex=True)
rc('font', family='serif')

voltage = 220

notes = r"\noindent $V_2 = {0:.5} V$".format(voltage)

plt.annotate(notes, xy=(5,5), xytext=(7,7))
plt.show()

It works perfectly, but my first nitpick is that V is a unit of measure, therefore it should be in text mode, instead of (italicized) math mode. I try the following string:

notes = r"\noindent $V_2 = {0:.5} \text{V}$".format(voltage)

That raises an error, because {curly braces} are the ownership of Python's string formatting syntax. In the above line, only {0:.5} is correct; {V} is treated as a stranger. For example:

s1 = "Hello"
s2 = "World!"
print "Some string {0} {1}".format(s1, s2)

should give Some string Hello World!.

How do I make sure that TeX's {curly braces} do not interfere with Python's {curly braces}?

Kit
  • 30,365
  • 39
  • 105
  • 149

3 Answers3

29

You have to double the braces to be treated literally:

r"\noindent $V_2 = {0:.5} \text{{V}}$".format(voltage)

BTW, you can also write

\text V

but the best is

\mathrm V

since a unit is not really a text symbol.

Philipp
  • 48,066
  • 12
  • 84
  • 109
6

You double-curly-brace them:

>>> print '{{asd}} {0}'.format('foo')
{asd} foo
Blender
  • 289,723
  • 53
  • 439
  • 496
2

Instead of using python formating with '{}' I prefere formating with '%', so I can avoid a bunch of braces.

So in order to render something like 3*pi/2, I use following code

r'\frac{%.0f\pi}{2}' % (3)

instead of

r'\frac{{{:.0f}\pi}}{{2}}'.format(3)

Using it in Jupyter, the code would look like:

from IPython.display import display, Math, Latex
display(Math(  r'\frac{%.0f\pi}{2}' % (3)  ))
Hol Wi
  • 21
  • 3