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

Résolu/Fermé
elias - 19 déc. 2022 à 15:03
yg_be Messages postés 22730 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 - 20 déc. 2022 à 16:50

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

yg_be Messages postés 22730 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 477
19 déc. 2022 à 20:06

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

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
yg_be Messages postés 22730 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 477
20 déc. 2022 à 09:48

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
elias > yg_be Messages postés 22730 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024
20 déc. 2022 à 10:55

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
yg_be Messages postés 22730 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 477 > elias
20 déc. 2022 à 13:38

Quel est ton souci avec les dimensions de im?

0
elias > yg_be Messages postés 22730 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024
20 déc. 2022 à 13:45

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
yg_be Messages postés 22730 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 477 > elias
20 déc. 2022 à 14:11

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

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
yg_be Messages postés 22730 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 477
20 déc. 2022 à 14:26

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

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
yg_be Messages postés 22730 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 477
20 déc. 2022 à 15:25

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

0

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

Posez votre question

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
yg_be Messages postés 22730 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 477
20 déc. 2022 à 16:50

Je trouve que ceci donne mieux:

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