24

I have used the python package to include Python in my LaTeX document which works fine.

I am trying to access the Python variables/calculations outside of \begin{python} ... \end{python}, without luck.

My question is: Can I? or How do I access variables/calculations within Python code embedded in LaTeX?

Simple example

\begin{python}
tdegc = 25.0
tdegf = (tdegc - 32.0)/1.0
print 'T in DegC is ', tdegc , ' in Deg F is ', tdegf
\end{python}

My calculations show that $\mbox{tdegf} = $ tdegf (this is the value for tdegf)

doncherry
  • 54,637
Krishnan
  • 249
  • 1
  • 2
  • 3
  • 1
    My experience with this python.sty is limited, but I thought it was only for producing output - it doesn't modify the tex environment outside of the python environment, so there's no way to access these variables. – Thomas Oct 30 '11 at 15:48
  • I am not 100% clear on your intent. Are you interested in using (say) \tdegf in your main document (outside \begin{python}...\end{python}) and it should print the equivalent of \tdegc in Fahrenheit? As in -3.889? By the way, your Fahrenheit calculation is incorrect: tdegf = (tdegc - 32.0)*(5/9). – Werner Oct 30 '11 at 15:51
  • 3
    I don't see the reason why the author of the package must be mentioned this explicitly. A link to the package would be much better. I only found a dangling link to the authors former University page. – Martin Scharrer Oct 30 '11 at 15:56
  • Oops - I meant "1.8" (and thanks) - I see what the problem is - the python.sty file is just a way to embed python and not access tex variables – Krishnan Oct 30 '11 at 16:50
  • 1
    It is not a way to embed Python, only a way to lay out Python source code within a LaTeX document. – reinierpost Jan 30 '12 at 13:09
  • The python.sty link is broken. – user2661923 Aug 08 '22 at 02:59

8 Answers8

15

I've played around a little with the sagetex package (designing tests which can be randomized) and I think you should look into its documentation. sagetex allows you incorporate Sage into your LaTeX code. Since Sage is based Python, you can run Python using sagetex. There is a \sage command that lets you jump back in to work with variables you've defined before, which I think is the issue you are concerned about. You can find some examples on CTAN. Here's a cut down sample:

\documentclass[10pt]{article} 
\usepackage{sagetex} 

\begin{document} 
\begin{sagesilent}%use sage without producing output
n, x = var('n x')
a = ZZ.random_element(-10,10)
while a == 0:
   a = ZZ.random_element(-10,10)
b = ZZ.random_element(-10,10)
c = ZZ.random_element(-10,10)
d = ZZ.random_element(2,9)
ratexp1 = (a*n)/(a*n+1)
ratexp2 = (d**(d*n-1))/((d+1)**n)
ratexp3 = 1/(a*x+b)
deriv1 = diff(ratexp3,x,1)
\end{sagesilent}
\begin{enumerate} %creates the numbering for the problems.
\item $\Sigma_{n=1}^{\infty} \sage{ratexp2}$

\vskip 2 in %leaves 2 inches of space for student work
\item Find the derivative of $\sage{ratexp3}$. The answer is $\sage{deriv1}$

\vskip 2 in %leaves 2 inches of space for student work
\item Consider the series: $ \Sigma_{n=1}^{\infty}\sage{ratexp1} $
Find a formula for $s_n$, the nth partial sum. 
\end{enumerate}
\end{document}

The code is choosing random elements for a,b,c,d but throws out a if a=0. I then defined rational expressions (to be used in the problems) and even calculated a derivative. At that point, I left Sage but I can still access the past work (even in math mode) using the \sage command; eg. \sage{ratexp2}.

Note: although I used a = ZZ.random_element(-10,10) to produce random integers, you can use the typical Python commands to produce random numbers. You'll also need to install Sage, along with the style file. Just like the python package, compiling the code produces an intermediate file (.sage file) which you process with Sage. sagetex is a very powerful package.

doncherry
  • 54,637
DJP
  • 12,451
  • I will try embedding python into \begin{sagetex} and try to access the variables that way - that may be the solution indeed ... thanks – Krishnan Oct 30 '11 at 17:20
  • @DJP I was wondering if you know if it is possible to use these variable, say your "a" as an argument of a LaTeX command. For example, I tried using a \foreach \n in {1,...,\sage{n}}{whatever here} where n was previously assigned a value in a sageblock environment, but it would not compile. I'm thinking it is because the way \sage return it's value is different than rather typing a fixed number – Jean-Sébastien Feb 07 '14 at 07:50
  • There's some mixing of the Sage and LaTeX variables ( page 5-6 of the documentation link) but not (that I know of) in the way you're asking. Generally, you'd have the \foreach structure coded within the Sage block as a for loop in Python which would then get inserted as a string. Look at my answer for the Weierstrass function: Sage calculate the points which are then inserted into a LaTeX statement within the sagesilent block: output += r"\draw[blue, thin]...and then put into Latex with the \sagestr command – DJP Feb 07 '14 at 22:51
  • My last comment was partially wrong (no Python for loop needed). Inside a sagesilent block there would be something like: output += r"\foreach \n in {1,...,%d}{whatever here}"%(n) where n was the variable. There are various issues that can arise depending on the specifics of "whatever here"; eg, Sage integers and Python Integers are different. It's difficult to say for sure without knowing the specific problem. – DJP Feb 08 '14 at 17:48
11

There is also SympyTeX, a package that allows you to use the complete functionality of python and sympy within your LaTeX document.

Here is an example: Using sympy within your LaTeX document is as easy as $2+2=\sympy{2+2}$.

You can write a block, and then use the variables defined later in your code!
\begin{sympyblock}
    x = sympy.Symbol('x')
    h = sympy.integrate(1+x,x)
\end{sympyblock}
The variable $h$, how can be called using {\verb \sympy{h} }, and you will get $h =  
\sympy{h}$. Similarly, the integral of $1+x^4$ is $\sympy{sympy.integrate(1+x**4,x)}$.

This will result in: enter image description here

As far as I know it is not yet available on CTAN but you can download it from the author's homepage: SympyTeX

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036
Alexander
  • 9,163
10

A comparison between all the options.

package name LaTeX CTAN pers. sync 1-run shell depython? engine. exp. overleaf version note
⟨column header long name⟩ is it really LaTeX? is it on CTAN? persistent variable? sync only need a single run? requires shell escape? can be converted to a Python-independent TeX document? Engine independent? have expandable commands? works on overleaf? compatible with which Python version? additional notes
robust-externalize yes yes no yes yes (*) optional yes yes no yes -
pyluatex yes yes yes yes yes yes no no yes -
pythontex yes yes yes no no no partially with depythontex script yes no no Python 2.7 or 3.2+ to insert plots you can use matplotlib .savefig() then \includegraphics the result, I guess.
sympytex yes yes yes no no no can attach the generated .sout file with the TeX document yes no requires Python 2 provides \sympyplot command to insert a plot; requires sympy package
sagetex yes yes yes no no no can attach the generated .sout file with the TeX document; partially with makestatic.py (unmaintained) yes no provides \sageplot command
pythonimmediate (my package) yes yes yes yes yes yes no(t yet) yes no(t yet) yes Python 3 works without LuaTeX, but commands are unexpandable (for now). Also better debugging/traceback support etc. (see package description)
python yes yes no yes yes yes no yes no seems unmaintained, incompatible with LuaTeX
Lunatic Python yes no yes yes yes yes (required for LuaTeX to load dynamically linked libraries) no but can be implemented manually no yes need to install/configure manually, probably the most convenient solution to share data between Lua side and Python side e.g. to use Python callback from Lua?
PyLaTeX preprocessor output LaTeX no yes yes yes no yes yes - -
TexSurgery preprocessor output LaTeX yes ? ? ? ? ? ? - -
hybrid-latex preprocessor output LaTeX yes (the .sty file is named pylatex) ? ? ? ? ? ? - -
PlasTeX no no probably yes yes yes no probably yes yes - -
Pweave no, it's markdown no probably yes yes yes no - yes - -
(note: have 0 user) QS-TEX preprocessor output LaTeX no - no no no ? yes ? seems to not have any users at all...?

of course there's also the "no package" solution but this one doesn't really count as you can implement anything.

Clarification on some of the columns

  • "sync" means that the Python run are interleaved with TeX run. So for example the TeX code following a Python environment only runs after the Python code finishes running.

    if this is false, some other packages use the approach of collecting all the Python code to be run on the first pass, run Python, then re-run LaTeX with the result.

  • "single run" means you only need to run LaTeX once. (maybe a few more times to resolve reference, but the Python feature does not require that)

  • "persistent variable" means the Python variables from one Python code block can be reused in subsequent Python code blocks.

  • "depython" means whether it's possible to modify the document so that it's compilable on machines without Python. "partially" means it's possible for some subset of "well-behaved" documents.

  • actually "shell escape" doesn't really matter, as Python code can execute arbitrary system shell command anyway. So if you want to compile untrusted code that use this feature you need to sandbox the Python process as well

  • "engine independent" means it can run on all of pdflatex/xelatex/lualatex. Otherwise it only runs on lualatex

(*): robust-externalize is single-run if shell-escape is enabled.

sympytex/sagetex requires sympy/sage to be installed correspondingly.

Note, I don't necessarily have experience on many packages here, I only check the manual for how it should be invoked etc.

user202729
  • 7,143
  • .note. a hack to get sympytex to work on overleaf (basic feature at least https://gist.github.com/user202729/34c1243cf3f612332dad60760054c3ed) – user202729 Aug 08 '22 at 01:56
  • There's also codebraid but it works with Markdown of pandoc instead of LaTeX. – user202729 Nov 16 '22 at 11:14
  • How to get your package pythonimmediate working under pdflatex? – Krantz Oct 28 '23 at 16:16
  • @Krantz The package is supported on PDFLaTeX. To avoid cluttering the comment area maybe move to chat or https://github.com/user202729/pythonimmediate-tex/discussions ? – user202729 Oct 29 '23 at 01:00
  • Awesome comparison! I just added an answer based on robust-externalize, as far as I see it fulfills all boxes. – tobiasBora Mar 12 '24 at 17:38
9

This is too long to be a comment, since the OP's intent is not 100% clear.

There is usually very little in terms of interaction between environments used and whatever is contained within them that can be used outside of that environment. Typically, environments are used to format its contents in a general way, performing certain operations at the start of the environment (at \begin{<env>}) and some at the end (at \end{<env>}).

If you're interested in performing calculations within your document, or at least mimic it without going through the trouble of specifying things verbatim, the fp package provides floating point operations at compile time. Here is a short example:

enter image description here

\documentclass{article}
\usepackage[nomessages]{fp}% http://ctan.org/pkg/fp
\newcommand{\degrees}[1][C]{{}^\circ\mathrm{#1}}% degrees celcius/fahrenheit
% Celcius <-> Fahrenheit conversions: http://en.wikipedia.org/wiki/Fahrenheit
\begin{document}
Some temperature conversions:
\begin{itemize}
  \item \FPeval{\result}{round((89.2-32)*(5/9),1)}%
    $89.2\degrees[F]=\result\degrees$
  \item \FPeval{\result}{round(25*(9/5)+32,1)}%
    $25\degrees=\result\degrees[F]$
\end{itemize}
\end{document}

As a result, it is now possible to include python code in your document and you could use inline fp code (outside the python environment) to calculate expressions that you can typeset in your document.

Werner
  • 603,163
  • I am familiar with the fp package, it is very nice and useful and do use it often ... with python, there are other things I can do (!) – Krishnan Oct 30 '11 at 17:19
  • @Krishnan: Sure. The python package and similarly-named python environment doesn't allow you to do that. @DJP's answer does something similar to what you're after, only for Sage. – Werner Oct 30 '11 at 17:21
  • 2
    Another option is to use luatex to get acess to a proper programming language within TeX. – Aditya Oct 30 '11 at 17:56
5

Look for the pythontex package on CTAN or gitHub. It lets you embed python code (including sympy and pyplot code) in your LaTeX document and access the results for typesetting. You can directly access variable values or have a Python print statement generate LaTeX commands. It handles individual statements (\py{math.cos(3.14159/4)} or \py{"The square root of 2. is {0:3g}".format(math.sqrt(2.))} or whole blocks of code. It will also allow code to be typeset with or without execution.

cgnieder
  • 66,645
Bill N
  • 652
  • 6
  • 16
1

You can also use Pweave, which unlike pythontex only needs to run once.

Here is a more complex example that includes localisation.

0

Using the Python library tikzpy will allow to do the contrary. Create tikz images via Python

fco
  • 129
0

Just to do a bit of advertisement for my robust-externalize library, here is a solution. Note that this library is not just made for python, so it might be less specialized than above libraries, but it will be certainly significantly more flexible as it can:

  • cache any sort of content, including images (python generated, online…),
  • can deal with any language,
  • can be used with or without shell-escape for the first compilation (no need to compile twice with shell-escape), no shell-escape needed for later compilations (cached result)
  • provide functions to compile in parallel, clean the cache,
  • can also get variables from latex via set placeholder eval={__foo__}{\foo}.
  • print the code next to the result
  • automatically run some code (python imports…) if some string are found…
  • compilation can be externalized to some servers (say you need GPU access, special libraries…)
  • it works on overleaf, arxiv…

If you don't have a recent enough CTAN (needs version v2.7 for the indentation not to cause any issue), just copy the .sty file from https://github.com/leo-colisson/robust-externalize/ in your project.

Version 1: just compute some variables in python and reuse them later

It is simpler to compile with pdflatex --shell-escape document.tex, but not mandatory, see doc.

\documentclass{article}

\usepackage{robust-externalize} \robExtConfigure{ enable fallback to manual mode, % avoid error if shell escape is forgotten/not used, print instead the command in the pdf }

\begin{document}

\begin{CacheMeCode}{python, do not include pdf} import math myvalue = math.sqrt(37) write_to_out(r"\gdef\myvalue{" + str(myvalue) + r"}") \end{CacheMeCode}

The value we computed via the above python code is \myvalue.

\end{document}

enter image description here

Version 2: make this into a tiny macro

This library does not provide directly a single macro to do the above in one line (maybe I should provide this option at some points), but it is fairly easy to make one, and you can customize it at will, for instance to wrap your code with some functions automatically, wrap the output with some tikz figures etc:

\documentclass{article}

\usepackage{robust-externalize}

\robExtConfigure{ enable fallback to manual mode, % avoid error if shell escape is forgotten/not used, print instead the command in the pdf new preset={my python exec}{ python, custom include command={\mytmpvalue}, add import={import math}, set placeholder={ROBEXT_MAIN_CONTENT}{write_to_out(r"\gdef\mytmpvalue{" + str(ROBEXT_MAIN_CONTENT_ORIG)+ r"}")} }, }

\begin{document}

You can compute simple values like \cacheMe[my python exec]{math.sqrt(42)}.

\end{document}

enter image description here

Version 3: include both the code and the result

We provide directly a preset for this (NB: make sure to use v2.8 or above as 2.7 introduces a bug where an empty line is added in front of the code):

\documentclass{article}

\usepackage{robust-externalize} \usepackage{pythonhighlight} \usepackage[most]{tcolorbox}

\robExtConfigure{ enable fallback to manual mode, % avoid error if shell escape is forgotten/not used, print instead the command in the pdf }

\begin{document}

\begin{CacheMeCode}{do not remove leading spaces, python print code and result, set title={The for loop}} for name in ["Alice", "Bob"]: print(f"Hello {name}") \end{CacheMeCode}

\end{document}

enter image description here

Version 4: matplotlib images

For a basic pdf-based rendering, you can use the following code, for a more advanced integration with LaTeX with a pgf backend, see my answer here https://tex.stackexchange.com/a/710138/116348

\documentclass{article}

\usepackage{robust-externalize} \usepackage{pythonhighlight} \usepackage[most]{tcolorbox}

\robExtConfigure{ enable fallback to manual mode, % avoid error if shell escape is forgotten/not used, print instead the command in the pdf }

\begin{document}

\begin{figure}[ht] \centering \begin{CacheMeCode}{python, add to includegraphics options={width=\linewidth}} import matplotlib.pyplot as plt import matplotlib year = [2014, 2015, 2016, 2017, 2018, 2019] tutorial_count = [39, 117, 111, 110, 67, 29] plt.plot(year, tutorial_count, color="#6c3376", linewidth=2) plt.title("Simple plot") plt.xlabel('Year') plt.ylabel('Number of futurestud.io Tutorials') print(get_filename_from_extension(".pgf")) plt.savefig("ROBEXT_OUTPUT_PDF") \end{CacheMeCode} \caption{Test}% \end{figure}

\end{document}

enter image description here

tobiasBora
  • 8,684