Modélisation de l’évolution de la fréquence des allèles

Professeurs référents :

M FAURY (ISN)

Mme GOUHIER (SVT)

Objectif

Modéliser l’évolution des différents allèles d’un gène au cours du temps. Deux moteurs principaux sont responsables d’une modification des allèles :

Ces deux facteurs induisent respectivement une modification aléatoire ou orientée de la fréquence des allèles dans une population.

Cahier des charges

A chaque génération, seuls certains allèles sont transmis par les parents à leur descendants. De la même façon, le logiciel doit modéliser un tirage au sort de certains allèles à partir d’une population de départ.

Paramètres d’entrée Sorties graphiques
  • nombre d’allèles différents : de 2 à 5
  • nombre d’individus dans la population : de 5 à 100
  • nombre de générations : pas de limite
  • taux de mutation (si activé)
  • image de la population de départ
  • image de la population à la génération n+1
  • graphique montrant l’évolution du nombre d’allèles au cours du temps

Tâches à réaliser

Élève 1 (CLEMENT Arthur)
Élève 2 (HERNANDEZ Martin)
Élève 3 (WILLIAM Aurore)
Représentation graphique d’une population Interface utilisateur avec schéma Algorithme de calcul

La dérive génétique

Programme final

[reveal heading= »%image% Code Python »]
from tkinter import *
from random import *
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
# implement the default mpl key bindings
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure


###############################################################################
# Constantes
###############################################################################
couleurs = ["red","purple","green","yellow","blue"]

# Liste de toutes les générations successives
generations = []
z = 1 # un compteur d'individus

# Liste de points pour les courbes
X = []
Y = []

def allele():
    n = scale2.get() # Nombre d'allèles différents
    return list(range(n))


def premiereG():
    """ Construit une première génération
        (aléatoire)
    """
    x=scale.get()   # Nombre d'individus dans la population
    n=scale2.get()  # Nombre d'allèles différents
    a=x//n
    gen=a*allele()
    for b in range(0,x%n):
        gen.append(b)
    shuffle(gen)
    return gen

    
def Gsuivante(gen):
    """ Renvoie la génération suivante de gen
    """
    a=entrée.get()
    x=scale.get()   # Nombre d'individus dans la population

    gen2=[]
    for b in range(x):
        gen2.append(choice(gen))
    if var.get()==1:
        for b in range(x):
            a=int(a)
            if a==randint(1,a):
                gen2[b]=randint(0,4)
    return gen2
    

def afficher():
    if var.get()==1:
        label.grid(row=3, column=3, sticky='e', padx=55)
        entrée.grid(row=3, column=3, sticky='e',padx=20)
    elif var.get()==0:
        entrée.grid_forget()
        label.grid_forget()

        
def demarrer():
    """ Fonction lancée après appui sur le bouton "Démarrer"
    """
    global generations, X, Y
    # On cache des choses ...
    scale.grid_forget()
    scale2.grid_forget()
    btn_demarrer.grid_forget()
    mutations.grid_forget()
    label.grid_forget()
    entrée.grid_forget()
    
    # On en affiche d'autres
    btn_tirer.grid(row=11, column=0)
    btn_tttirer.grid(row=11, column=1)
    btn_reinitialiser.grid(row=11, column=2)
    
    # Titre du bocal de droite
    C.create_text(120,230,text="Génération n°1")
    
    generations.append(premiereG())
    
    plt.grid(True)
    plt.set_title("fréquence des allèles")
    plt.set_xlabel('génération')
    plt.set_ylabel('fréquence (%)')
    plt.axis([0,1,0,100])
    plt.set_xticks(range(1))
    
    nall = scale2.get()
    X = []
    Y = [[] for i in range(nall)]

    for i, y in enumerate(Y):
        plt.plot(X, y)
    

def reinitialiser():
    global generations
    generations = []
    
    scale.grid(row=1, column=3,padx=5,pady=5)
    scale2.grid(row=2, column=3,padx=5,pady=5)
    btn_demarrer.grid(row=4, column=3,padx=5,pady=5)
    mutations.grid(row=3, column=3,padx=5,pady=5)
    btn_tirer.grid_forget()
    btn_tttirer.grid_forget()
    btn_tirerBis.grid_forget()
    btn_tttirerBis.grid_forget()
    btn_reinitialiser.grid_forget()
    btn_generation.grid_forget() 
    mutations.deselect()
    
    B.delete(ALL)
    B.create_line(18,20,18,222,18,222,222,222,222,222,222,20)
    
    C.delete(ALL)
    C.create_line(18,20,18,222,18,222,222,222,222,222,222,20)

    plt.cla()
    fig.canvas.draw()

    
def tirer(bocal, gen, z):
    """ Place l'allele de l'individu "z"
        de génération "gen"
        dans le bocal
    """
    x = scale.get()

    y = gen[z-1]

    if z < x:
        if z<11:
            a=20*(z)
            b=20*(z+1)
            bocal.create_oval(a,200,b,220, fill=couleurs[y], width=0)
        if 10<z<21:
            a=20*(z-10)
            b=20*(z-9)
            bocal.create_oval(a,180,b,200, fill=couleurs[y], width=0)
        if 20<z<31:
            a=20*(z-20)
            b=20*(z-19)
            bocal.create_oval(a,160,b,180, fill=couleurs[y], width=0)
        if 30<z<41:
            a=20*(z-30)
            b=20*(z-29)
            bocal.create_oval(a,140,b,160, fill=couleurs[y], width=0)
        if 40<z<51:
            a=20*(z-40)
            b=20*(z-39)
            bocal.create_oval(a,120,b,140, fill=couleurs[y], width=0)
        if 50<z<61:
            a=20*(z-50)
            b=20*(z-49)
            bocal.create_oval(a,100,b,120, fill=couleurs[y], width=0)
        if 60<z<71:
            a=20*(z-60)
            b=20*(z-59)
            bocal.create_oval(a,80,b,100, fill=couleurs[y], width=0)
        if 70<z<81:
            a=20*(z-70)
            b=20*(z-69)
            bocal.create_oval(a,60,b,80, fill=couleurs[y], width=0)
        if 80<z<91:
            a=20*(z-80)
            b=20*(z-79)
            bocal.create_oval(a,40,b,60, fill=couleurs[y], width=0)
        if 90<z:
            a=20*(z-90)
            b=20*(z-89)
            bocal.create_oval(a,20,b,40, fill=couleurs[y], width=0)
    else:
        btn_tirer.grid_forget()
        btn_generation.grid(row=11, column=1)
        btn_tttirer.grid_forget()
        tracer()



def incrementer_generations():
    btn_generation.grid_forget()
    generations.append(Gsuivante(generations[-1]))
    global z
    
    i=len(generations)
    z=1
    
    if i%2==1:
        B.grid(row=1, column=0, rowspan=10)
        C.grid(row=1, column=1, rowspan=10)
        C.delete(ALL)
        C.create_line(18,20,18,222,18,222,222,222,222,222,222,20)
        btn_tirer.grid(row=11, column=0)
        btn_tirerBis.grid_forget()
        btn_tttirer.grid(row=11, column=1)
        btn_tttirerBis.grid_forget()
        C.create_text(120,230,text="Génération n°"+str(i))

    else:
        C.grid(row=1, column=0, rowspan=10)
        B.grid(row=1, column=1, rowspan=10)
        B.delete(ALL)
        B.create_line(18,20,18,222,18,222,222,222,222,222,222,20)
        btn_tirerBis.grid(row=11, column=0)
        btn_tirer.grid_forget()
        btn_tttirerBis.grid(row=11, column=1)
        btn_tttirer.grid_forget()
        B.create_text(120,230,text="Génération n°"+str(i))


    

def tttirer(bocal, gen):
    """ Termine de placer toutes les allèles
        de la génération "gen"
        à partir de l'individu "z"
    """
    global z
    x = scale.get()

    btn_tirer.grid_forget()
    btn_tttirer.grid_forget()
    
    while z-1 < x:
        tirer(bocal, gen, z)
        z += 1



def decompte(gen):
    """ Renvoie une liste de décompte
        du nombre d'allèle dans la génération "gen"
    """
    frequence=[]
    a={}
    for b in gen:
        if b in a.keys():
            a[b]+=1
        else:
            a[b]=1
            
    nall = scale2.get()
    for c in range(nall):
        if c in a.keys():
            frequence.append(a[c])
        else:
            frequence.append(0)
    
    y = len(gen)
    
    # On met les quantité en %
    frequence = [i/y*100 for i in frequence]
    
    return frequence

    
def tracer():
    global X, Y
    
    X = list(range(len(generations)))

    nall = scale2.get()
    
    for i, f in enumerate(decompte(generations[-1])):
        Y[i].append(f)
        
    c = ['r', 'm', 'g', 'y', 'b']
    c = c[:nall]
    
    plt.cla()

    for i, y in enumerate(Y):
        plt.plot(X, y,c[i])
    
    fig.canvas.draw()



###############################################################################
fenetre = Tk()
fenetre.title("Modélisation de l’évolution de la fréquence des allèles")
fenetre['bg']='bisque'

titre = Label(fenetre, text="Modélisation de l’évolution de la fréquence des allèles", bg='bisque')
titre.configure(fg = 'gray')
titre.grid(row=0, column=0, columnspan=100)
#fenetre.minsize(955,527)
#fenetre.maxsize(955,527)


scale=Scale(orient='horizontal', from_=5, to=100,
            resolution=1, tickinterval=10, length=400, 
            activebackground='black', 
            bg='gray', bd=5, fg='white', 
            label="Nombre d'individus dans la population", 
            troughcolor='white')
scale.grid(row=1, column=3,padx=5,pady=5)


scale2=Scale(orient='horizontal', from_=2, to=5,
             resolution=1, tickinterval=1, length=200, 
             activebackground='black', 
             bg='gray', bd=5, fg='white', 
             label="Nombre d'allèles différents", 
             troughcolor='white')
scale2.grid(row=2, column=3,padx=5,pady=5)


entrée=Entry(width=5)
label=Label(text="1/")

var = IntVar()
mutations = Checkbutton(fenetre, text="Autoriser les mutations", bg='gray', command=afficher, variable=var)
mutations.grid(row=3, column=3,padx=5,pady=5)

btn_demarrer = Button(fenetre, text = "Démarrer", command = demarrer)
btn_demarrer.grid(row=4, column=3,padx=5,pady=5)

btn_tirer = Button(fenetre, text = "tirer une boule", command=lambda: tirer(C, generations[-1], z))
btn_tirerBis = Button(fenetre, text = "tirer une boule", command=lambda: tirer(B, generations[-1], z))

btn_tttirer = Button(fenetre, text = "tout tirer", comman=lambda: tttirer(C, generations[-1]))
btn_tttirerBis = Button(fenetre, text = "tout tirer", comman=lambda: tttirer(B, generations[-1]))

btn_reinitialiser= Button(fenetre, text = "réinitialiser", command = reinitialiser)

btn_generation= Button(fenetre, text ="génération suivante", command = incrementer_generations)


# Les bocaux
B=Canvas(width=240, height=240)
B.grid(row=1, column=0, rowspan=10,padx=10,pady=10)
B.create_line(18,20,18,222,18,222,222,222,222,222,222,20)

C=Canvas(width=240, height=240)
C.grid(row=1, column=1, rowspan=10,padx=10,pady=10)
C.create_line(18,20,18,222,18,222,222,222,222,222,222,20)



###############################################################################
# Zone du graphique
###############################################################################
z_plot = Frame(fenetre)
fig = Figure(figsize=(5, 4), dpi=100)
plt = fig.add_subplot(111)


# a tk.DrawingArea
canvas = FigureCanvasTkAgg(fig, master=z_plot)
canvas.show()
canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)

toolbar = NavigationToolbar2TkAgg(canvas, z_plot)
toolbar.update()
canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1)
z_plot.grid(row=12, column=0, columnspan=3,padx=10,pady=10)


fenetre.mainloop()
[/reveal]

La sélection naturelle

La sélection des allèles n’est dans ce cas plus aléatoire, mais dépend d’un facteur influençant leur transmission (paramètres de l’environnement, action d’un prédateur, …)

Vous aimerez aussi...

6 réponses

  1. Chedid-Ferreira dit :

    Bonjour, je suis très intéressée par votre projet  » modélisation de l’évolution de la fréquence des allèles  » cependant je suis une débutante je ne sais pas par où commencer ni comment m’y prendre. pouvez vous m’aidez pour que ce projet soit au top 🙂

  2. chedid dit :

    bonjour ! Desolee pour le dérangement mas y aurait-il moyen s’il vous plait de me fournir de facon detaille le fonctionnement des boucles parce que je ne comprend pas grand chose et pourtant je le trouve très complet et fort interessant

    merci de votre comprehension et pour votre aide

  3. chedid dit :

    bonjour ! Desolee pour le dérangement mas y aurait-il moyen s’il vous plait de me fournir de facon detaille le fonctionnement des boucles parce que je ne comprend pas grand chose et pourtant je le trouve très complet et fort interessant

    merci de votre comprehension et pour votre aide qui a été très utile dans l’avancement de mon travail

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *