Tuesday 15 October 2013

PythonTeX

I write technical documents in LaTeX, and my programming language of choice is (currently) Python.  I’m about to start writing a large LaTeX document that will have lots of figures drawn with Python’s matplotlib.  So, I was wondering, wouldn’t it be nice if there was some support for including these more directly in the document.  I went surfing, and came across PythonTeX, by Geoffrey M. Poore.

PythonTeX doesn’t just allow you to put figures in your LaTeX, it allows whole chunks of Python, with the results embedded in the output.  After watching a YouTube video on the capabilities, I thought it looked interesting, so I decide to give it a go: it might well be useful, and anyway it’s a great displacement activity from actually starting writing that document.

It wasn’t a particularly onerous installation process, as LaTeX and Python installations go.  In order to get the test document, pythontex_gallery.tex, to format properly, I just had to:
  1. download PythonTeX
  2. run LaTeX on the provided example file pythontex_gallery.tex (I use TeXnicCenter)
  3. give LaTeX permission install several macro packages (as warned by the PythonTeX installation documentation)
  4. from the command line, run pythontex.py pythontex_gallery.tex
  5. scrutinise the error messages to see I needed pygments.style, sympy, and scipy  (again, as warned by the PythonTeX installation documentation)
  6. go to the pygments page, and see that it recommends installation via ez_setup
  7. go to the ez_setup page, and download it
  8. from the command line, run python ez_setup.py
  9. download the relevant pygments “egg”
  10. from the command line, run easy_install Pygments-1.6-py2.7.egg
  11. download and install sympy
  12. download and install scipy (hence discovering that it is pronounced “sigh pie”, not “skippy”)
  13. from the command line, run pythontex.py pythontex_gallery.tex
  14. run LaTeX on pythontex_gallery.tex again
At this point out popped a LaTeX pdf with figures, equations, integrals, and expression derivations all produced from the embedded python!

Now that I have everything installed, all I have to do to generate this pdf from scratch is:
  1. run LaTeX on pythontex_gallery.tex
  2. from the command line, run pythontex.py pythontex_gallery.tex
  3. run LaTeX on pythontex_gallery.tex again
Simples!

There is also a handy utility to convert the LaTeX file with embedded python into a stand-alone LaTeX document, suitable for other people to process.  (This is essential if the document needs to be sent off for publication, for example.)
  1. edit the LaTeX file to include the depythontex=true option in the pythontex package
  2. run LaTeX on pythontex_gallery.tex again
  3. run pythontex.py pythontex_gallery.tex again
  4. run depythontex.py --graphicspath pythontex_gallery.tex final.tex
Then anyone can run LaTeX on final.tex without needing PythonTeX.

Having installed PythonTeX, and checked that it can at least process the supplied test file, I next needed to check that I can get it to produce the kind of diagrams I want.

So I wrote a short LaTeX document with the body:
\begin{pylabcode}
n = 16
m = 6
figure(figsize=(n*0.2, m*0.2))
gca().axison = False
x = 8
y = 4
fill( (x,x+1,x+1,x), (y,y,y+1,y+1), 'r', linewidth=0)
for i in range(0,n+1):
    ii = (i,i)
    jj = (0,m)
    plot(ii,jj,'0.4', linewidth=0.2)
for j in range(0,m+1):
    ii = (0,n)
    jj = (j,j)
    plot(ii,jj,'0.4', linewidth=0.2)
savefig('myplot.pdf', bbox_inches='tight')
\end{pylabcode}

\includegraphics{myplot.pdf}

This is a \pylab{'${0} \\times {1} = {2}$'.format(n, m, n * m)}
square grid, with a red block at $(\pylab{x},\pylab{y})$.

The top bit is some python code to draw a grid and a red square, and the bottom bit is some explanatory LaTeX text.  Going through the LaTeX-PythonTex-LaTeX process gives:
Excellent.  I can use it to draw diagrams in situ.  The great advantage this approach has is that I can keep all my code for the figures in the same file as the LaTeX text, so there will be much less chance for fragments to wander off and get lost.

As shown in the code above, the LaTeX can include references to python variables, which is how the caption part is generated.  Then, if I decide that I want a slightly different figure, I just edit this single file, change only the values assigned to n,m,x,y in the python part, and get something like:

The new variable values have changed the drawn figure, and these changes have also been propagated to the caption, including the calculation of the product.  This gives a much more sophisticated form of cross referencing.

I’m sold!


No comments:

Post a Comment