221 votes

Générer une carte thermique dans MatPlotLib en utilisant un ensemble de données de dispersion

J'ai un ensemble de points de données X,Y (environ 10 000) qu'il est facile de représenter sous forme de diagramme de dispersion, mais que je voudrais représenter sous forme de carte thermique.

J'ai regardé les exemples dans MatPlotLib et ils semblent tous partir des valeurs des cellules de la carte thermique pour générer l'image.

Existe-t-il une méthode permettant de convertir un ensemble de x,y, tous différents, en une carte thermique (où les zones présentant une fréquence plus élevée de x,y seraient plus "chaudes") ?

0 votes

216voto

ptomato Points 24461

Si vous ne voulez pas d'hexagones, vous pouvez utiliser l'outil numpy histogram2d fonction :

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

# Generate some test data
x = np.random.randn(8873)
y = np.random.randn(8873)

heatmap, xedges, yedges = np.histogram2d(x, y, bins=50)
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]

plt.clf()
plt.imshow(heatmap.T, extent=extent, origin='lower')
plt.show()

Cela donne une carte thermique de 50x50. Si vous voulez, disons, 512x384, vous pouvez mettre bins=(512, 384) dans l'appel à histogram2d .

Exemple : Matplotlib heat map example

1 votes

Je ne veux pas être un idiot, mais comment faire pour que cette sortie se fasse vers un fichier PNG/PDF au lieu de s'afficher uniquement dans une session IPython interactive ? J'essaie de faire en sorte que ce soit une sorte d'affichage normal. axes dans laquelle je peux ajouter un titre, des étiquettes d'axe, etc. savefig() comme je le ferais pour n'importe quel autre graphique typique de Matplotlib.

3 votes

@gotgenes : n'a pas plt.savefig('filename.png') travail ? Si vous voulez obtenir une instance d'axe, utilisez l'interface orientée objet de Matplotlib : fig = plt.figure() ax = fig.gca() ax.imshow(...) fig.savefig(...)

1 votes

En effet, merci ! Je suppose que je ne comprends pas bien imshow() fait partie de la même catégorie de fonctions que scatter() . Honnêtement, je ne comprends pas pourquoi imshow() convertit un tableau 2d de floats en blocs de couleur appropriée, alors que je comprends ce que signifie scatter() est censé faire avec un tel tableau.

119voto

doug Points 29567

Sur Matplotlib lexique, je pense que tu veux un hexbin parcelle.

Si vous n'êtes pas familier avec ce type d'intrigue, c'est juste un histogramme bivarié dans lequel le plan xy est tessellé par une grille régulière d'hexagones.

Ainsi, à partir d'un histogramme, vous pouvez simplement compter le nombre de points qui tombent dans chaque hexagone, discrétiser la région de traçage comme un ensemble de Windows pour affecter chaque point à l'une de ces fenêtres ; enfin, pour faire correspondre les fenêtres à un fichier matrice de couleurs et vous obtenez un diagramme hexagonal.

Bien qu'ils soient moins couramment utilisés que les cercles ou les carrés, les hexagones sont intuitivement un meilleur choix pour la géométrie du conteneur de binning :

  • les hexagones ont symétrie plus proche du voisin (par exemple, les bacs carrés ne le font pas, par exemple, la distance de un point sur la frontière d'un carré à un point à l'intérieur de ce carré n'est pas partout égal) et

  • L'hexagone est le n-polygone le plus élevé qui donne plan régulier tessellation (Par exemple, vous pouvez sans risque refaire le sol de votre cuisine avec des carreaux de forme hexagonale car il n'y aura pas d'espace vide entre les carreaux lorsque vous aurez terminé - ce qui n'est pas vrai pour tous les autres polygones supérieurs à n, n >= 7).

( Matplotlib utilise le terme hexbin l'intrigue ; il en va de même pour (AFAIK) tous les bibliothèques de traçage pour R ; je ne sais toujours pas si c'est le terme généralement accepté pour les intrigues de ce type, mais je pense que c'est probable étant donné que hexbin est le diminutif de binning hexagonal qui décrit l'étape essentielle de la préparation des données pour l'affichage).


from matplotlib import pyplot as PLT
from matplotlib import cm as CM
from matplotlib import mlab as ML
import numpy as NP

n = 1e5
x = y = NP.linspace(-5, 5, 100)
X, Y = NP.meshgrid(x, y)
Z1 = ML.bivariate_normal(X, Y, 2, 2, 0, 0)
Z2 = ML.bivariate_normal(X, Y, 4, 1, 1, 1)
ZD = Z2 - Z1
x = X.ravel()
y = Y.ravel()
z = ZD.ravel()
gridsize=30
PLT.subplot(111)

# if 'bins=None', then color of each hexagon corresponds directly to its count
# 'C' is optional--it maps values to x-y coordinates; if 'C' is None (default) then 
# the result is a pure 2D histogram 

PLT.hexbin(x, y, C=z, gridsize=gridsize, cmap=CM.jet, bins=None)
PLT.axis([x.min(), x.max(), y.min(), y.max()])

cb = PLT.colorbar()
cb.set_label('mean value')
PLT.show()   

enter image description here

0 votes

Qu'est-ce que cela signifie que "les hexagones ont une symétrie plus proche du voisin" ? Vous dites que "la distance entre un point sur la bordure d'un carré et un point à l'intérieur de ce carré n'est pas partout égale" mais la distance par rapport à quoi ?

10 votes

Pour un hexagone, la distance du centre à un sommet joignant deux côtés est également plus longue que celle du centre au milieu d'un côté, mais le rapport est plus petit (2/sqrt(3) 1,15 pour l'hexagone contre sqrt(2) 1,41 pour le carré). Le cercle est la seule forme où la distance entre le centre et chaque point de la bordure est égale.

7 votes

@Jaan Pour un hexagone, chaque voisin est à la même distance. Il n'y a pas de problème de 8-voisins ou de 4-voisins. Pas de voisins diagonaux, juste un type de voisin.

33voto

Si vous utilisez la version 1.2.x

import numpy as np
import matplotlib.pyplot as plt

x = np.random.randn(100000)
y = np.random.randn(100000)
plt.hist2d(x,y,bins=100)
plt.show()

gaussian_2d_heat_map

3voto

Zipo Points 63

Cette réponse Méthode efficace de calcul de la densité de points irrégulièrement espacés a introduit plus de méthodes sur la façon de le faire plus efficacement et précisément. j'espère que cela peut aider

2voto

meepmeep Points 774

Créez un tableau à deux dimensions correspondant aux cellules de votre image finale, appelé par exemple heatmap_cells et l'instancie en tant que zéro.

Choisissez deux facteurs d'échelle qui définissent la différence entre chaque élément du tableau en unités réelles, pour chaque dimension, par exemple x_scale et y_scale . Choisissez-les de manière à ce que tous vos points de données se situent dans les limites du tableau de la carte thermique.

Pour chaque point de données brut avec x_value et y_value :

heatmap_cells[floor(x_value/x_scale),floor(y_value/y_scale)]+=1

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X