Heatmap 3D sur python, problème pour la variable Z

Résolu
elias -  
yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   -

Bonjour,

J'ai le code ci-dessous (méthode du plus proche voisin) qui permet d'obtenir une heatmap d'un jeu de donnée X et Y. J'aimerais avoir accès à la valeur de l'intensité (ou densité ?) en chaque point pour pouvoir introduire une variable Z (qui depend donc de X et Y ) qui me permettrait de tracer une heatmap 3D pour mon problème. Cependant je n'arrive pas à avoir cette nouvelle variable Z, si vous avez des idées n'hésitez pas à m'aider :)

Merci

le code :

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm


def data_coord2view_coord(p, vlen, pmin, pmax):
    dp = pmax - pmin
    dv = (p - pmin) / dp * vlen
    return dv


def nearest_neighbours(xs, ys, reso, n_neighbours):
    im = np.zeros([reso, reso])
    extent = [np.min(xs), np.max(xs), np.min(ys), np.max(ys)]

    xv = data_coord2view_coord(xs, reso, extent[0], extent[1])
    yv = data_coord2view_coord(ys, reso, extent[2], extent[3])
    for x in range(reso):
        for y in range(reso):
            xp = (xv - x)
            yp = (yv - y)

            d = np.sqrt(xp**2 + yp**2)

            im[y][x] = 1 / np.sum(d[np.argpartition(d.ravel(), n_neighbours)[:n_neighbours]])

    return im, extent


n = 1000
xs = np.random.randn(n)
ys = np.random.randn(n)
resolution = 250

fig, axes = plt.subplots(2, 1)

for ax, neighbours in zip(axes.flatten(), [0,64]):
    if neighbours == 0:
        ax.plot(xs, ys, 'k.', markersize=2)
        ax.set_aspect('equal')
        ax.set_title("Scatter Plot")
    else:
        im, extent = nearest_neighbours(xs, ys, resolution, neighbours)
        ax.imshow(im, origin='lower', extent=extent, cmap=cm.jet)
        ax.set_title("Smoothing over %d neighbours" % neighbours)
        ax.set_xlim(extent[0], extent[1])
        ax.set_ylim(extent[2], extent[3])
plt.show()


Windows / Edge 108.0.1462.54

5 réponses

  1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     

    bonjour,

    quand tu partages du code, peux-tu préciser le langage (python)?  il s'affichera alors mieux.

    Il me semble que ton heatmap affiche bien la valeur du Z.  Que veux-tu changer exactement?

    0
  2. elias
     

    Bonsoir,

    D'accord j'y veillerai la prochaine fois.

    En fait, je veux utiliser plot_surface(X,Y,Z) pour le tracé mais je ne sais pas quoi renseigné pour Z, je n'ai pas l'expression exacte (et Z doit être de dimension 2).

    Merci

    0
    1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       

      Tu veux utiliser comme Z la valeur de l'intensité de ton heatmap?

      As-tu écrit le code que tu nous montres?  Le comprends-tu?  Comment peux-tu faire cet exercice sans comprendre le code de départ?

      0
      1. elias > yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention  
         

        Oui je veux utiliser Z comme la valeur de l'intensité de ma heatmap. Le code n'est pas le miens mais on me l'a expliqué et je pense l'avoir compris. Cependant le détail que je ne comprend pas est au sujet de la sortie im qui va avoir une dimension qui depend de la résolution et c'est cela que je n'arrive pas à exploiter . 

        0
      2. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588 > elias
         

        Quel est ton souci avec les dimensions de im?

        0
      3. elias > yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention  
         

        quand j'essaye d'utiliser plot_surface(X,Y,Z) , on me dit qu'il y a :

        "Mismatch is between arg 0 with shape (1000,) and arg 2 with shape (250, 250)."

        Je comprend bien pourquoi il y a ce message d'erreur mais je vois pas comment résoudre ce problème.

        0
      4. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588 > elias
         

        Ce message d'erreur ne nous permet pas de t'aider si tu ne nous montres pas le code complet.

        Est-ce la première fois que tu utilises plot_surface?  As-tu lu la documentation et analysé des exemples?

        0
  3. elias
     

    Voila le code que j'ai utilisé. Oui j'ai verifié la documentation, j'ai un problème au niveau de ma variable d'intensité seulement.

    ax = plt.axes(projection='3d')
    z = nearest_neighbours(xs, ys, 250, 64)[0]
    
    ax.plot_surface(xs, ys, z , cmap='YlGnBu_r',vmin=0,vmax=1)
    
    0
    1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       

      Je pense que tu ne veux pas faire un heatmap 3d, mais plutôt une représentation 3d d'un heatmap 2d.  Je me trompe?

      Dans la documentation de plot_surface(), que dit-on de la dimension des paramètres X et Y?

      0
  4. elias
     

    Oui exactement, je veux une representation 3D d'un heatmap 2D, je me suis mal exprimé.

    X,Y et Z sont censés être des 2D arrays

    0
    1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       

      xs et ys doivent donc être en 2D, ce qui n'est pas le cas.

      0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. elias
     

    Effectivement, j'étais concentré sur le Z mais c'était X et Y que je devais changer. J'ai pu obtenir ma heat map avec le code ci dessous. Merci pour votre aide

    pas = (extent[1]-extent[0])/250
    XE = [extent[0] + n*pas for n in range(0,250) ]
    pas2 = (extent[3]-extent[2])/250
    YE = [extent[2] + n*pas2 for n in range(0,250) ]
    
    X,Y = np.meshgrid(XE,YE)
    fig = plt.figure(figsize =(14, 9))
    
    ax = plt.axes(projection='3d')
    
    z = nearest_neighbours(X1, Y1, 250, 64)[0]
    
    ax.plot_surface(X, Y, z , cmap=cm.jet)
    ax.view_init(35,20)
    
    0
    1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       

      Je trouve que ceci donne mieux:

      ax.plot_surface(X, Y, z , cmap=cm.jet, c=z)
      0