Processing math: 100%

Planche de Galton, Python et LaTeX. Sur cette page, j’ai expliqué comment simuler l’expérience de la planche de Galton à l’aide de Python. Je souhaite dans cet article aller plus loin en obtenant un fichier PDF du résultat obtenu avec LATEX.

Il y a deux approches possibles: utiliser PythonTeX, ou générer le fichier LATEX directement en Python.

Planche de Galton, Python et LaTeX : approche avec pythontex

C’est l’approche la moins intéressante. En effet, cette compilation a un inconvénient majeur: à chaque fois, il est nécessaire de supprimer les fichiers auxiliaires créés par la compilation pour obtenir un nouveau document. Je m’explique: je compile le document suivant via pythontex.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
\documentclass{article}
\usepackage{tikz}
\usepackage{pythontex}
\usepackage[margin=5mm]{geometry}
\begin{document}
\begin{center}
\begin{pycode}
from random import choice
def simulation_galton(c = 7 , n = 20):
base = c * [0]
for bille in range(n):
position = c // 2
for clou in range(c-1):
position += choice([-1,1])/2
base[ int(position) ] += 1
return base
def graph_latex( L ):
ligne = '\\begin{tikzpicture}\n'
for i in range(len(L)): # pour chaque élément de L
if L[i] != 0: # si l'élément est non nul
for y in range(1,L[i]): # on trace L[i] billes à la verticale
ligne += '\\shade[ball color = blue] (' + str(i+0.5) + ' , ' + str(y) + ') circle (5mm);\n'
ligne += '\\draw[very thick] (0,0.5) -- (' + str(len(L)) + ',0.5);\n'
for x in range( len(L)+1 ):
ligne += '\\draw[very thick] ('+str(x)+','+str(0.5)+') -- ('+str(x)+','+str( max(L) )+');\n'
for y in range( len(L) ):
for x in range( y ):
ligne += '\\fill[gray] (' + str(1+3-y/2+x) + ',' + str(max(L) + 0.5 + 1.5*(len(L)-y-1)) + ') circle (1mm);\n'
ligne += '\\end{tikzpicture}'
return ligne
print( graph_latex( simulation_galton(n=50) ) )
\end{pycode}
\end{center}
\end{document}
\documentclass{article} \usepackage{tikz} \usepackage{pythontex} \usepackage[margin=5mm]{geometry} \begin{document} \begin{center} \begin{pycode} from random import choice def simulation_galton(c = 7 , n = 20):     base = c * [0]     for bille in range(n):         position = c // 2         for clou in range(c-1):             position += choice([-1,1])/2                      base[ int(position) ] += 1     return base def graph_latex( L ):     ligne = '\\begin{tikzpicture}\n'     for i in range(len(L)): # pour chaque élément de L         if L[i] != 0: # si l'élément est non nul             for y in range(1,L[i]): # on trace L[i] billes à la verticale                 ligne += '\\shade[ball color = blue] (' + str(i+0.5) + ' , ' + str(y) + ') circle (5mm);\n'          ligne += '\\draw[very thick] (0,0.5) -- (' + str(len(L)) + ',0.5);\n'     for x in range( len(L)+1 ):         ligne += '\\draw[very thick] ('+str(x)+','+str(0.5)+') -- ('+str(x)+','+str( max(L) )+');\n'     for y in range( len(L) ):         for x in range( y ):             ligne += '\\fill[gray] (' + str(1+3-y/2+x) + ',' + str(max(L) + 0.5 + 1.5*(len(L)-y-1)) + ') circle (1mm);\n'     ligne += '\\end{tikzpicture}'     return ligne      print( graph_latex( simulation_galton(n=50) ) )    \end{pycode} \end{center} \end{document}
\documentclass{article}
\usepackage{tikz}
\usepackage{pythontex}
\usepackage[margin=5mm]{geometry}

\begin{document}

\begin{center}
\begin{pycode}
from random import choice

def simulation_galton(c = 7 , n = 20):
    base = c * [0]
    for bille in range(n):
        position = c // 2
        for clou in range(c-1):
            position += choice([-1,1])/2
            
        base[ int(position) ] += 1

    return base

def graph_latex( L ):
    ligne = '\\begin{tikzpicture}\n'
    for i in range(len(L)): # pour chaque élément de L
        if L[i] != 0: # si l'élément est non nul
            for y in range(1,L[i]): # on trace L[i] billes à la verticale
                ligne += '\\shade[ball color = blue] (' + str(i+0.5) + ' , ' + str(y) + ') circle (5mm);\n'
    
    ligne += '\\draw[very thick] (0,0.5) -- (' + str(len(L)) + ',0.5);\n'
    for x in range( len(L)+1 ):
        ligne += '\\draw[very thick] ('+str(x)+','+str(0.5)+') -- ('+str(x)+','+str( max(L) )+');\n'
    for y in range( len(L) ):
        for x in range( y ):
            ligne += '\\fill[gray] (' + str(1+3-y/2+x) + ',' + str(max(L) + 0.5 + 1.5*(len(L)-y-1)) + ') circle (1mm);\n'
    ligne += '\\end{tikzpicture}'
    return ligne
    
print( graph_latex( simulation_galton(n=50) ) )   
\end{pycode}

\end{center}
\end{document}

et j’obtiens le PDF suivant:

Mais à ce stade, si je ne fais rien de plus que compiler à nouveau, j’obtiens exactement le même document. Or, ce que je voudrais, c’est une autre simulation… Pour se faire, je suis obligé de supprimer le répertoire pythontex-files-temp créé lors de la compilation via pythontex.

Ce n’est pas pratique… C’est pour cela que je préfère la seconde façon.

Approche avec génération du code LATEX en Python

Cette approche est à mon sens bien plus efficace.

On part du programme Python suivant:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from random import choice
from os import system
def simulation_galton(c = 7 , n = 20):
base = c * [0]
for bille in range(n):
position = c // 2
for clou in range(c-1):
position += choice([-1,1])/2
base[ int(position) ] += 1
return base
def graph_latex( L ):
ligne = '\\documentclass{standalone}\n'
ligne += '\\usepackage{tikz}\n'
ligne += '\\begin{document}\n'
ligne += '\\begin{tikzpicture}\n'
for i in range(len(L)): # pour chaque élément de L
if L[i] != 0: # si l'élément est non nul
for y in range(1,L[i]): # on trace L[i] billes à la verticale
ligne += '\\shade[ball color = blue] (' + str(i+0.5) + ' , ' + str(y) + ') circle (5mm);\n'
ligne += '\\draw[very thick] (0,0.5) -- (' + str(len(L)) + ',0.5);\n'
for x in range( len(L)+1 ):
ligne += '\\draw[very thick] ('+str(x)+','+str(0.5)+') -- ('+str(x)+','+str( max(L) )+');\n'
for y in range( len(L) ):
for x in range( y ):
ligne += '\\fill[gray] (' + str(1+3-y/2+x) + ',' + str(max(L) + 0.5 + 1.5*(len(L)-y-1)) + ') circle (1mm);\n'
ligne += '\\end{tikzpicture}\n'
ligne += '\\end{document}'
return ligne
"""
création du fichier LaTeX
"""
latex = graph_latex( simulation_galton(n=50) )
fichier = open('galton.tex' , 'w', encoding = 'utf8')
fichier.write( latex )
fichier.close()
"""
compilation via pdflatex
"""
system('pdflatex galton.tex')
system('start galton.pdf')
from random import choice from os import system def simulation_galton(c = 7 , n = 20): base = c * [0] for bille in range(n): position = c // 2 for clou in range(c-1): position += choice([-1,1])/2 base[ int(position) ] += 1 return base def graph_latex( L ): ligne = '\\documentclass{standalone}\n' ligne += '\\usepackage{tikz}\n' ligne += '\\begin{document}\n' ligne += '\\begin{tikzpicture}\n' for i in range(len(L)): # pour chaque élément de L if L[i] != 0: # si l'élément est non nul for y in range(1,L[i]): # on trace L[i] billes à la verticale ligne += '\\shade[ball color = blue] (' + str(i+0.5) + ' , ' + str(y) + ') circle (5mm);\n' ligne += '\\draw[very thick] (0,0.5) -- (' + str(len(L)) + ',0.5);\n' for x in range( len(L)+1 ): ligne += '\\draw[very thick] ('+str(x)+','+str(0.5)+') -- ('+str(x)+','+str( max(L) )+');\n' for y in range( len(L) ): for x in range( y ): ligne += '\\fill[gray] (' + str(1+3-y/2+x) + ',' + str(max(L) + 0.5 + 1.5*(len(L)-y-1)) + ') circle (1mm);\n' ligne += '\\end{tikzpicture}\n' ligne += '\\end{document}' return ligne """ création du fichier LaTeX """ latex = graph_latex( simulation_galton(n=50) ) fichier = open('galton.tex' , 'w', encoding = 'utf8') fichier.write( latex ) fichier.close() """ compilation via pdflatex """ system('pdflatex galton.tex') system('start galton.pdf')
from random import choice
from os import system

def simulation_galton(c = 7 , n = 20):
    base = c * [0]
    for bille in range(n):
        position = c // 2
        for clou in range(c-1):
            position += choice([-1,1])/2
            
        base[ int(position) ] += 1

    return base

def graph_latex( L ):
    ligne = '\\documentclass{standalone}\n'
    ligne += '\\usepackage{tikz}\n'
    ligne += '\\begin{document}\n'
    ligne += '\\begin{tikzpicture}\n'
    for i in range(len(L)): # pour chaque élément de L
        if L[i] != 0: # si l'élément est non nul
            for y in range(1,L[i]): # on trace L[i] billes à la verticale
                ligne += '\\shade[ball color = blue] (' + str(i+0.5) + ' , ' + str(y) + ') circle (5mm);\n'
    
    ligne += '\\draw[very thick] (0,0.5) -- (' + str(len(L)) + ',0.5);\n'
    for x in range( len(L)+1 ):
        ligne += '\\draw[very thick] ('+str(x)+','+str(0.5)+') -- ('+str(x)+','+str( max(L) )+');\n'
    for y in range( len(L) ):
        for x in range( y ):
            ligne += '\\fill[gray] (' + str(1+3-y/2+x) + ',' + str(max(L) + 0.5 + 1.5*(len(L)-y-1)) + ') circle (1mm);\n'
    ligne += '\\end{tikzpicture}\n'
    ligne += '\\end{document}'
    return ligne

"""
création du fichier LaTeX
"""
latex = graph_latex( simulation_galton(n=50) )
fichier = open('galton.tex' , 'w', encoding = 'utf8')
fichier.write( latex )
fichier.close()

"""
compilation via pdflatex
"""

system('pdflatex galton.tex')
system('start galton.pdf')

Il va d’une part simuler une expérience (ici, avec 7 colonnes et 50 billes), générer le fichier LATEX, le compiler et afficher le PDF, comme celui-ci par exemple:

planche de galton python latex

Il est alors aisé de modifier légèrement le programme Python pour générer autant d’expériences que souhaité.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
"""
création des fichiers LaTeX & PDF
"""
ext = [ 'log' , 'tex' , 'aux' ]
for k in range(5):
latex = graph_latex( simulation_galton(n=50) )
fichier = open('galton-'+str(k+1)+'.tex' , 'w', encoding = 'utf8')
fichier.write( latex )
fichier.close()
"""
compilation via pdflatex
"""
system('pdflatex galton-'+str(k+1)+'.tex')
for e in ext:
system('erase galton-' + str(k+1) + '.' + e)
""" création des fichiers LaTeX & PDF """ ext = [ 'log' , 'tex' , 'aux' ] for k in range(5): latex = graph_latex( simulation_galton(n=50) ) fichier = open('galton-'+str(k+1)+'.tex' , 'w', encoding = 'utf8') fichier.write( latex ) fichier.close() """ compilation via pdflatex """ system('pdflatex galton-'+str(k+1)+'.tex') for e in ext: system('erase galton-' + str(k+1) + '.' + e)
"""
création des fichiers LaTeX & PDF
"""
ext = [ 'log' , 'tex' , 'aux' ]
for k in range(5):
    latex = graph_latex( simulation_galton(n=50) )
    fichier = open('galton-'+str(k+1)+'.tex' , 'w', encoding = 'utf8')
    fichier.write( latex )
    fichier.close()

    """
    compilation via pdflatex
    """

    system('pdflatex galton-'+str(k+1)+'.tex')
    for e in ext:
        system('erase galton-' + str(k+1) + '.' + e)

Ici, j’ai opté pour le fait de supprimer tous les fichiers qui ne servent à rien pour ne garder que les fichiers PDF.

À noter que je suis sous Windows 10; j’utilise donc la commande « erase ». Sous Linux et MacOS, il me semble que c’est la commande « rm <fichier.ext> ».

La simulation de ces expériences est au programme de spécialité mathématiques en Terminale. Cette dernière approche peut donc aider les enseignant·e·s à construire un cours avec illustrations.


0 0 votes
Évaluation de l'article
S’abonner
Notification pour
guest


0 Commentaires
Le plus ancien
Le plus récent Le plus populaire
Commentaires en ligne
Afficher tous les commentaires
0
Nous aimerions avoir votre avis, veuillez laisser un commentaire.x