Partage
  • Partager sur Facebook
  • Partager sur Twitter

Traçage de distance avec flèches

Dessin Pyhton

Sujet résolu
    22 juillet 2021 à 15:50:57

    Bonjour,

    Je vous écris ce message afin de vous demander de l'aide concernant le dessin d'une flèche (indiquant la largeur à mi-hauteur) que je souhaiterai inclure sur un graphique.

    Voici ci-dessous l'image du graphique :

    Etant débutant sur Python, la seul manière que j'ai trouvé d'inclure la flèche indiquant la largeur à mi-hauteur (avec la valeur de la largeur) sur ce graphique est d'utiliser la syntaxe de code avec pyplot.annotate.

    Voici ci-dessous mon code :

    #############################################################################################################################
    #Spectre d'émission
    #############################################################################################################################
    #Importation de données d'un fichier CSV
    
    #Importation du module numpy afin de lire le contenu du fichier csv et simplification en np
    import numpy as np
    
    #Importation du module matplotlib.pyplot pour construire le graphique et simplification en plt
    import matplotlib.pyplot as plt
    
    #Importation du module scipy.interpolate pour interpoler des données avec une courbe d'approche
    from scipy.interpolate import splrep, sproot, splev
    
    #Recherche des coordonnéees des points dans le fichier csv
    #Les données sont séparées par des "," à  partir de la 2 ème ligne (notée 1)
    pointage = np.loadtxt("em9_spectra.csv",delimiter=',',skiprows=1)
    
    #Lecture des abscisses x issues de la troisième colonne (notée 2) du fichier csv
    #Les données se retrouveront dans un tableau d'une ligne
    x=pointage[:,2]
    
    #Lecture des ordonnées y issues de la sixième colonne (notée 5) du fichier csv
    #Les données se retrouveront dans un tableau d'une ligne
    y=pointage[:,5]
    
    print(type(y))
    print("Abscisses x en nm :",x)
    print("Ordonnées y en counts :",y)
    
    #Défini la valeur max de l'intensité
    #Ou utiliser fonction max(liste) prédéfinie
    def maximumIndices(liste):
        """ 
        Détermine valeur max de l'intensité
        Entrée : liste
        Sortie : intensité max
        """
        maxi = liste[0]
        longueur=len(liste)
        for i in range(longueur):
            if liste[i] >= maxi:
                maxi = liste[i]
        return maxi
    
    print("Intensite max =", maximumIndices(y))
    valeur = x[np.where(y==maximumIndices(y))] # Détermine la longueur d'onde dans x associée à l'intensité max dans y
    print("Longueur d'onde (en nm):", valeur)
    
    #Défini le FWHM du spectre d'intensité
    class MultiplePeaks(Exception): pass
    class NoPeaksFound(Exception): pass
    
    def fwhm(x, y, k=3):
        """
        Détermine la largeur à mi-hauteur d'un ensemble de points, x et y.
    
        On suppose qu'il n'y a qu'un seul pic présent dans l'ensemble de données. La fonction utilise une interpolation 
        spline d'ordre k.
        """
    
        half_max = maximumIndices(y)/2
        s = splrep(x, y - half_max, k=k)
        roots = sproot(s)
    
        if len(roots) > 2:
            raise MultiplePeaks("L'ensemble de données semble avoir plusieurs pics, et "
                    "ainsi le FWHM ne peut pas être déterminé.")
        elif len(roots) < 2:
            raise NoPeaksFound("Aucuns pics appropriés ont été trouvés dans l'ensemble de données; probablement "
                    "l'ensemble de données est plat (par exemple, tous valent zéros).")
        else:
            return abs(roots[1] - roots[0])
    
    print("FWHM (en nm)=", fwhm(x,y))
    
    #Affiche un repère prédéfini
    plt.axis([425,600,0,1200])
    
    plt.xlabel('Wavelength (nm)')           # Affiche la légende sur l'axe des abscisses
    plt.ylabel('Intensity (A.U.)')         # Affiche la légende sur l'axe des ordonnées
    plt.text(valeur, maximumIndices(y), r'$\lambda_{max}$ = 511 nm', fontsize=14, color='r') # Ajout de texte
    plt.plot(x,y,"b-")               # Trace une liaison entre les points en bleu
    plt.show()                        # Montre le graphique à l'écran

    Voici ci-dessous l'exemple d'utilisation de la fonction annotate :

    import matplotlib.pyplot as plt
    
    plt.annotate(
        '', xy=(1, 10), xycoords='data',
        xytext=(1, 8), textcoords='data',
        arrowprops={'arrowstyle': '<->'})
    plt.annotate(
        'D = 1', xy=(1, 9), xycoords='data',
        xytext=(5, 0), textcoords='offset points')
    
    plt.show()

    Pour finir, pourriez-vous me dire les étapes que je dois effectuer sur mon code (ayant du mal à voir la manière de trouver les couples xy et xytext), s'il vous plaît.

    Répondez-moi quand vous aurez du temps libre.

    Je vous en serai très reconnaissant.

    Merci de votre compréhension.

    -
    Edité par MilinoKEROWGODAGE 23 juillet 2021 à 11:17:02

    • Partager sur Facebook
    • Partager sur Twitter
      23 juillet 2021 à 15:04:07

      tu peux avoir 2 annotations:

      • une pour tracer la double flèche entre tes 2 points de la courbe:
      • une pour afficher le texte correspondant à cette position

      1-Pour la double flèche, xy c'est les coordonnées de ton point le plus le plus à gauche, et xytext celles de ton point le plus à droite; ces 2 points tu dois les avoir dans ton tableau (à vue de nez, ça doit être vers xy=(500,505) et xytext=(520,505) , il faut trouver les 2 valeurs de x pour lesquelles y vaut half_max)

      2-Pour la 2nde annotation, tu peux prendre pour xy la coordonnée du 2nd point (le xytext de la précédente annotation); pour le xytext, c'est la coordonnée à laquelle tu veux mettre le texte (tu peux le définir en coordonnées xy par rapport aux données, ou tu peux définir un offset par rapport à xy en ajoutant le paramètre textcoords='offset points' ou 'offset pixels' selon que tu veux définir l'écart en terme de coordonnées de données ou de distance graphique.

      Si tu définies xytext=(540,505) sans paramètre textcoords, tu positionnes le texte aux coordonnées (540,505) de ton graphique

      Si tu définies xytext=(100,0) avec textcoords='offset points', tu positionnes le texte aux coordonnées (620,505) de ton graphique (en supposant que xy=(520,505)

      Si tu définies xytext=(100,0) avec textcoords='offset pixels', tu positionnes le texte à 100 pixels à droite (0 décalage en hauteur) du point xy=(520,505)

      Tu peux faire des essais pour voir ce qui va le mieux et le plus facile.

      (la doc d'annotate > https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.annotate.html )

      • Partager sur Facebook
      • Partager sur Twitter
        23 juillet 2021 à 22:22:10

        Bonsoir,

        Merci pour l'aide et c'est d'ailleurs ce que j'ai fait car j'ai déjà résolu ce problème.

        • Partager sur Facebook
        • Partager sur Twitter

        Traçage de distance avec flèches

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        • Editeur
        • Markdown