Processing math: 100%

Comment créer automatiquement à l’aide de Python et de LaTeX un arbre de Bernoulli en probabilités ?

Je vais vous montrer l’utilisation d’une fonction Python que je viens d’écrire, et que les abonné·e·s trouveront en fin d’article.

LaTeX et Python: exemples d’arbres de Bernoulli

La fonction Python qui créée en LaTeX un arbre de Bernoulli

L’appel de la fonction nécessite obligatoirement deux paramètres: la hauteur de l’arbre et la probabilité du succès. Par exemple,

>>> bernoulli_tree(3,0.2)

va automatiquement créer un fichier LATEX puis le compiler, pour ensuite afficher le PDF:

Comme on peut le remarquer, les points décimaux ont été remplacés par une virgule.

Une arbre de Bernoulli avec des probabilités fractionnaires: l’option « fraction »

Si l’on souhaite que les probabilités s’affichent sous forme fractionnaire, on utilisera l’option « fraction »:

>>> bernoulli_tree(3,0.2,fraction=True,espv=0.7)

Remarquez ici la présence d’un autre paramètre : espv, qui permet d’espacer davantage les nœuds du dernier niveau afin que les fractions s’affichent correctement.

Si la probabilité du succès ne peut pas être écrite sous forme décimale, mais uniquement sous forme fractionnaire, on pourra écrire:

>>> bernoulli_tree(3,'1/3',fraction=True,espx=1,espv=0.8,espvinter=0.5)

Un arbre moins large: l’option espx

>>> bernoulli_tree(3,0.2,espx=1,espv=0.7,espvinter=0.5)

Remarquez ici la présence du paramètre espvinter qui désigne l’espace vertical entre les « groupes » de couples (succès,échec) au dernier niveau.

Par de nom à la racine

Si vous ne souhaitez pas que Ω apparaisse à la racine, tapez:

>>> bernoulli_tree(3,'1/3',fraction=True,espx=1,espv=0.8,espvinter=0.5,root='')

Changer les styles

On peut changer les styles TiKZ de tous les objets de l’arbre (branches, nœuds et probabilités):

>>> bernoulli_tree(3,0.2,fraction=True,espv=1.1,espvinter=0.5,stylebranche='line width=1pt,color=blue!50!black',stylenoeud='color=red',styleproba='midway,circle,scale=.5,text=red,draw=red,fill=red!20',filename='arbre-bernoulli-06')

Ici, la seule limite est celle de votre imagination ! Vous pouvez utiliser tous les styles TiKZ que vous souhaitez pour personnaliser votre arbre. Alors, lâchez-vous !

Des fractions écrites « en ligne »

Jouer avec les espaces verticaux est quelques fois pénibles. Dans ce cas, on pourra utiliser la syntaxe suivante:

>>> bernoulli_tree(3,Fraction(3,7),filename='arbre-bernoulli-07')

La fonction Python qui permet de construire en LaTeX un arbre de Bernoulli

Les paramètres utilisés pour la fonction Python permettant de construire en LaTeX un arbre de Bernoulli

  • niveau : nombre entier désignant le niveau de l’arbre (nombre de répétitions de l’expérience de Bernoulli);
  • proba: nombre (float) ou chaîne de caractères (de la forme ‘p/q’) ou objet type Fraction(p,q)
  • succes = ‘S’: lettre désignant le succès. Par défaut, « S »
  • espv = 0.5: espace vertical entre les nœuds « succès/échec »
  • espvinter = 1: espace vertical (en cm) entre les blocs « succès/échec »
  • espx = 2: espace horizontal (en cm) entre chaque niveau
  • fraction = False: booléen pour signifier si les probabilités doivent être écrites sous forme fractionnaire ou non
  • root = ‘$\Omega$’: nom de la racine (syntaxe LATEX mathématique ou pas)
  • stylebranche =  »: style TiKZ des branches
  • stylenoeud =  »: style TiKZ des nœuds (les événements « succès » et « échecs »)
  • styleproba = ‘midway,fill=white,scale=.5’: style TiKZ des probabilités sur les branches
  • filename = ‘arbre’: nom du fichier à sauvegarder et à compiler

Les modules

  • ‘fraction’
    • >>> pip install fractions ou conda install fractions
  • ‘os’ et ‘os.path’ (pour manipulation système: sauvegarde, compilation)

Autres remarques

Il faut bien entendu au préalable avoir installé une distribution LATEX.

La fonction Python

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from fractions import Fraction
def bernoulli_tree( niveau,\
proba,\
succes = 'S',\
espv = 0.5,\
espvinter = 1,\
espx = 2,\
fraction = False,\
root = '$\\Omega$',\
stylebranche = '',\
stylenoeud = '',\
styleproba = 'midway,fill=white,scale=.5',
filename = 'arbre'):
# Stéphane Pasquet
# mathweb.fr
# 2022/07/02
# https://www.mathweb.fr/euclide/2022/07/02/latex-et-python-creer-un-arbre-de-bernoulli-automatiquement/
if fraction:
proba_num = Fraction(str(proba)).numerator
proba_denom = Fraction(str(proba)).denominator
if isinstance(proba,float):
proba_echec_num = Fraction(str(1-proba)).numerator
proba_echec_denom = Fraction(str(1-proba)).denominator
else:
proba_echec_num = Fraction(str(1-Fraction(proba))).numerator
proba_echec_denom = Fraction(str(1-Fraction(proba))).denominator
proba = '$\\frac{'+str(proba_num)+'}{'+str(proba_denom)+'}$'
probaechec = '$\\frac{'+str(proba_echec_num)+'}{'+str(proba_echec_denom)+'}$'
else:
probaechec = str(1-proba).replace(".",",")
proba = str(proba).replace(".",",")
tex = '\\documentclass{standalone}\n'
tex += '\\usepackage{tikz}\n'
tex += '\\usetikzlibrary{calc}\n'
tex += '\\setlength{\\parindent}{0pt}\n'
tex += '\\begin{document}\n'
tex += '\\begin{tikzpicture}\n'
tex += '\\tikzstyle{branche} = [ '+stylebranche+' ]\n'
tex += '\\tikzstyle{noeud} = [ '+stylenoeud+' ]\n'
tex += '\\tikzstyle{proba} = [ '+styleproba+' ]\n'
level = niveau
echec = '\\overline{' + succes + '}'
# placement des noeuds
while level != 0:
if level == niveau:
y = 0
for i in range(2**level):
if i%2 == 0:
tex += '\\node[noeud] (N' + str(level) + '-' + str(i) + ') at ({'+str(espx)+'*'+str(level)+'},'+str(y)+') {$'+succes+'$};\n'
y -= espv
else:
tex += '\\node[noeud] (N' + str(level) + '-' + str(i) + ') at ({'+str(espx)+'*'+str(level)+'},'+str(y)+') {$'+echec+'$};\n'
y -= espvinter
else:
for i in range(2**level):
if i%2 == 0:
tex += '\\node[noeud] (N' + str(level) + '-' + str(i) + ') at ($0.5*(N'+str(level+1)+'-'+str(2*i)+')+0.5*(N'+str(level+1)+'-'+str(2*i+1)+')+(-'+str(espx)+',0)$) \
{$'+succes+'$};\n'
else:
tex += '\\node[noeud] (N' + str(level) + '-' + str(i) + ') at ($0.5*(N'+str(level+1)+'-'+str(2*i)+')+0.5*(N'+str(level+1)+'-'+str(2*i+1)+')+(-'+str(espx)+',0)$) \
{$'+echec+'$};\n'
level -= 1
# tracé des branches
tex += '\\node[left,noeud] at ($0.5*(N1-0)+0.5*(N1-1)+(-'+str(espx)+',0)$) {'+root+'};\n'
tex += '\\draw[branche] ($0.5*(N1-0)+0.5*(N1-1)+(-'+str(espx)+',0)$) -- (N1-0) node[proba] {'+proba+'};\n'
tex += '\\draw[branche] ($0.5*(N1-0)+0.5*(N1-1)+(-'+str(espx)+',0)$) -- (N1-1) node[proba] {'+probaechec+'};\n'
for lev in range(1,niveau):
for i in range(2**lev):
tex += '\\draw[branche] (N'+str(lev)+'-'+str(i)+'.east) -- (N'+str(lev+1)+'-'+str(2*i)+') node[proba] {'+proba+'};\n'
tex += '\\draw[branche] (N'+str(lev)+'-'+str(i)+'.east) -- (N'+str(lev+1)+'-'+str(2*i+1)+') node[proba] {'+probaechec+'};\n'
tex += '\\end{tikzpicture}\n'
tex += '\\end{document}'
# sauvegarde du fichier LaTeX
from os.path import isfile
from os import remove, system
if isfile(filename+".tex"):
remove(filename+".tex")
fichier = open(filename+".tex","x")
fichier.write(tex)
fichier.close()
# compilation PdfLaTeX dans le répertoire courant
cmd = "pdflatex --shell-escape -synctex=1 -interaction=nonstopmode "+filename+".tex"
system(cmd)
cmd = "START "+filename+".pdf"
system(cmd)
from fractions import Fraction def bernoulli_tree( niveau,\ proba,\ succes = 'S',\ espv = 0.5,\ espvinter = 1,\ espx = 2,\ fraction = False,\ root = '$\\Omega$',\ stylebranche = '',\ stylenoeud = '',\ styleproba = 'midway,fill=white,scale=.5', filename = 'arbre'): # Stéphane Pasquet # mathweb.fr # 2022/07/02 # https://www.mathweb.fr/euclide/2022/07/02/latex-et-python-creer-un-arbre-de-bernoulli-automatiquement/ if fraction: proba_num = Fraction(str(proba)).numerator proba_denom = Fraction(str(proba)).denominator if isinstance(proba,float): proba_echec_num = Fraction(str(1-proba)).numerator proba_echec_denom = Fraction(str(1-proba)).denominator else: proba_echec_num = Fraction(str(1-Fraction(proba))).numerator proba_echec_denom = Fraction(str(1-Fraction(proba))).denominator proba = '$\\frac{'+str(proba_num)+'}{'+str(proba_denom)+'}$' probaechec = '$\\frac{'+str(proba_echec_num)+'}{'+str(proba_echec_denom)+'}$' else: probaechec = str(1-proba).replace(".",",") proba = str(proba).replace(".",",") tex = '\\documentclass{standalone}\n' tex += '\\usepackage{tikz}\n' tex += '\\usetikzlibrary{calc}\n' tex += '\\setlength{\\parindent}{0pt}\n' tex += '\\begin{document}\n' tex += '\\begin{tikzpicture}\n' tex += '\\tikzstyle{branche} = [ '+stylebranche+' ]\n' tex += '\\tikzstyle{noeud} = [ '+stylenoeud+' ]\n' tex += '\\tikzstyle{proba} = [ '+styleproba+' ]\n' level = niveau echec = '\\overline{' + succes + '}' # placement des noeuds while level != 0: if level == niveau: y = 0 for i in range(2**level): if i%2 == 0: tex += '\\node[noeud] (N' + str(level) + '-' + str(i) + ') at ({'+str(espx)+'*'+str(level)+'},'+str(y)+') {$'+succes+'$};\n' y -= espv else: tex += '\\node[noeud] (N' + str(level) + '-' + str(i) + ') at ({'+str(espx)+'*'+str(level)+'},'+str(y)+') {$'+echec+'$};\n' y -= espvinter else: for i in range(2**level): if i%2 == 0: tex += '\\node[noeud] (N' + str(level) + '-' + str(i) + ') at ($0.5*(N'+str(level+1)+'-'+str(2*i)+')+0.5*(N'+str(level+1)+'-'+str(2*i+1)+')+(-'+str(espx)+',0)$) \ {$'+succes+'$};\n' else: tex += '\\node[noeud] (N' + str(level) + '-' + str(i) + ') at ($0.5*(N'+str(level+1)+'-'+str(2*i)+')+0.5*(N'+str(level+1)+'-'+str(2*i+1)+')+(-'+str(espx)+',0)$) \ {$'+echec+'$};\n' level -= 1 # tracé des branches tex += '\\node[left,noeud] at ($0.5*(N1-0)+0.5*(N1-1)+(-'+str(espx)+',0)$) {'+root+'};\n' tex += '\\draw[branche] ($0.5*(N1-0)+0.5*(N1-1)+(-'+str(espx)+',0)$) -- (N1-0) node[proba] {'+proba+'};\n' tex += '\\draw[branche] ($0.5*(N1-0)+0.5*(N1-1)+(-'+str(espx)+',0)$) -- (N1-1) node[proba] {'+probaechec+'};\n' for lev in range(1,niveau): for i in range(2**lev): tex += '\\draw[branche] (N'+str(lev)+'-'+str(i)+'.east) -- (N'+str(lev+1)+'-'+str(2*i)+') node[proba] {'+proba+'};\n' tex += '\\draw[branche] (N'+str(lev)+'-'+str(i)+'.east) -- (N'+str(lev+1)+'-'+str(2*i+1)+') node[proba] {'+probaechec+'};\n' tex += '\\end{tikzpicture}\n' tex += '\\end{document}' # sauvegarde du fichier LaTeX from os.path import isfile from os import remove, system if isfile(filename+".tex"): remove(filename+".tex") fichier = open(filename+".tex","x") fichier.write(tex) fichier.close() # compilation PdfLaTeX dans le répertoire courant cmd = "pdflatex --shell-escape -synctex=1 -interaction=nonstopmode "+filename+".tex" system(cmd) cmd = "START "+filename+".pdf" system(cmd)
from fractions import Fraction

def bernoulli_tree( niveau,\
                    proba,\
                    succes = 'S',\
                    espv = 0.5,\
                    espvinter = 1,\
                    espx = 2,\
                    fraction = False,\
                    root = '$\\Omega$',\
                    stylebranche = '',\
                    stylenoeud = '',\
                    styleproba = 'midway,fill=white,scale=.5',
                    filename = 'arbre'):
    
    # Stéphane Pasquet
    # mathweb.fr
    # 2022/07/02
    # https://www.mathweb.fr/euclide/2022/07/02/latex-et-python-creer-un-arbre-de-bernoulli-automatiquement/
    
    if fraction:
        proba_num = Fraction(str(proba)).numerator
        proba_denom = Fraction(str(proba)).denominator
        if isinstance(proba,float):
            proba_echec_num = Fraction(str(1-proba)).numerator
            proba_echec_denom = Fraction(str(1-proba)).denominator
        else:
            proba_echec_num = Fraction(str(1-Fraction(proba))).numerator
            proba_echec_denom = Fraction(str(1-Fraction(proba))).denominator
        proba = '$\\frac{'+str(proba_num)+'}{'+str(proba_denom)+'}$'
        probaechec = '$\\frac{'+str(proba_echec_num)+'}{'+str(proba_echec_denom)+'}$'
    else:
        probaechec = str(1-proba).replace(".",",")
        proba = str(proba).replace(".",",")
        
    tex = '\\documentclass{standalone}\n'
    tex += '\\usepackage{tikz}\n'
    tex += '\\usetikzlibrary{calc}\n'
    tex += '\\setlength{\\parindent}{0pt}\n'
    tex += '\\begin{document}\n'

    tex += '\\begin{tikzpicture}\n'
    tex += '\\tikzstyle{branche} = [ '+stylebranche+' ]\n'
    tex += '\\tikzstyle{noeud} = [ '+stylenoeud+' ]\n'
    tex += '\\tikzstyle{proba} = [ '+styleproba+' ]\n'
    
    level = niveau
    echec = '\\overline{' + succes + '}'
    
    # placement des noeuds
    
    while level != 0:
        if level == niveau:
            y = 0
            for i in range(2**level):
                if i%2 == 0:
                    tex += '\\node[noeud] (N' + str(level) + '-' + str(i) + ') at ({'+str(espx)+'*'+str(level)+'},'+str(y)+') {$'+succes+'$};\n'
                    y -= espv
                else:
                    tex += '\\node[noeud] (N' + str(level) + '-' + str(i) + ') at ({'+str(espx)+'*'+str(level)+'},'+str(y)+') {$'+echec+'$};\n'
                    y -= espvinter
        else:
            for i in range(2**level):
                if i%2 == 0:
                    tex += '\\node[noeud] (N' + str(level) + '-' + str(i) + ') at ($0.5*(N'+str(level+1)+'-'+str(2*i)+')+0.5*(N'+str(level+1)+'-'+str(2*i+1)+')+(-'+str(espx)+',0)$) \
{$'+succes+'$};\n'
                else:
                     tex += '\\node[noeud] (N' + str(level) + '-' + str(i) + ') at ($0.5*(N'+str(level+1)+'-'+str(2*i)+')+0.5*(N'+str(level+1)+'-'+str(2*i+1)+')+(-'+str(espx)+',0)$) \
{$'+echec+'$};\n'
        
        level -= 1
    
    # tracé des branches
    
    tex += '\\node[left,noeud] at ($0.5*(N1-0)+0.5*(N1-1)+(-'+str(espx)+',0)$) {'+root+'};\n'
    tex += '\\draw[branche] ($0.5*(N1-0)+0.5*(N1-1)+(-'+str(espx)+',0)$) -- (N1-0) node[proba] {'+proba+'};\n'
    tex += '\\draw[branche] ($0.5*(N1-0)+0.5*(N1-1)+(-'+str(espx)+',0)$) -- (N1-1) node[proba] {'+probaechec+'};\n'
    
    for lev in range(1,niveau):
        for i in range(2**lev):
            tex += '\\draw[branche] (N'+str(lev)+'-'+str(i)+'.east) -- (N'+str(lev+1)+'-'+str(2*i)+') node[proba] {'+proba+'};\n'
            tex += '\\draw[branche] (N'+str(lev)+'-'+str(i)+'.east) -- (N'+str(lev+1)+'-'+str(2*i+1)+') node[proba] {'+probaechec+'};\n'

    tex += '\\end{tikzpicture}\n'
    tex += '\\end{document}'
    
    # sauvegarde du fichier LaTeX
    
    from os.path import isfile
    from os import remove, system
    
    if isfile(filename+".tex"):
        remove(filename+".tex")
    
    fichier = open(filename+".tex","x")
    fichier.write(tex)
    fichier.close()

    # compilation PdfLaTeX dans le répertoire courant

    cmd = "pdflatex  --shell-escape -synctex=1 -interaction=nonstopmode "+filename+".tex"
    system(cmd)
    cmd = "START "+filename+".pdf"
    system(cmd)

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
0
    0
    Votre panier
    Votre panier est vide