Visualisation de diagrammes de dispersion avec points de chevauchement dans matplotlib

je dois représenter environ 30 000 points dans un nuage de points dans matplotlib. Ces points appartiennent à deux classes différentes, donc je veux les dépeindre avec des couleurs différentes.

j'ai réussi à le faire, mais il y a un problème. Les points se chevauchent dans de nombreuses régions et la classe que je dépeint pour la dernière sera visualisée au-dessus de l'autre, le cachant. En outre, avec le nuage de points n'est pas possible de montrer combien les points se trouvent dans chaque région. J'ai aussi essayé de faire un 2d histogramme avec histogram2d et imshow, mais il est difficile de montrer les points appartenant aux deux classes d'une manière claire.

pouvez-vous suggérer un moyen de clarifier à la fois la distribution des classes et la concentration des points?

EDIT: pour être plus clair, c'est le lien à mon fichier de données au format "x,y,classe"

15
demandé sur markusian 2013-09-28 12:02:07

2 réponses

Une approche consiste à tracer les données comme un nuage de points avec un alpha de faible, de sorte que vous pouvez voir les différents points ainsi qu'une mesure approximative de la densité. (L'inconvénient, c'est que l'approche a une portée limitée de chevauchement qu'elle peut montrer, c'est-à-dire une densité maximale d'environ 1 alpha.)

Voici un exemple:

enter image description here

comme vous pouvez l'imaginer, en raison de la gamme limitée de chevauchements qui peuvent être exprimés, il ya un compromis entre la visibilité des points individuels et l'expression de la quantité de chevauchement (et la taille du marqueur, terrain, etc).

import numpy as np
import matplotlib.pyplot as plt

N = 10000
mean = [0, 0]
cov = [[2, 2], [0, 2]]
x,y = np.random.multivariate_normal(mean, cov, N).T

plt.scatter(x, y, s=70, alpha=0.03)
plt.ylim((-5, 5))
plt.xlim((-5, 5))
plt.show()

(je suppose ici que vous vouliez dire 30e3 points, pas 30e6. Pour 30e6, je pense qu'un type de graphique de densité moyenne serait nécessaire.)

19
répondu tom10 2016-11-09 17:38:46

vous pouvez aussi colorer les points en calculant d'abord une estimation de la densité du noyau de la distribution de la dispersion, et en utilisant les valeurs de densité pour spécifier une couleur pour chaque point de la dispersion. Modifier le code dans l'exemple précédent :

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde as kde
from matplotlib.colors import Normalize
from matplotlib import cm

N = 10000
mean = [0,0]
cov = [[2,2],[0,2]]

samples = np.random.multivariate_normal(mean,cov,N).T
densObj = kde( samples )

def makeColours( vals ):
    colours = np.zeros( (len(vals),3) )
    norm = Normalize( vmin=vals.min(), vmax=vals.max() )

    #Can put any colormap you like here.
    colours = [cm.ScalarMappable( norm=norm, cmap='jet').to_rgba( val ) for val in vals]

    return colours

 colours = makeColours( densObj.evaluate( samples ) )

 plt.scatter( samples[0], samples[1], color=colours )
 plt.show()

Scatter plot with density information

j'ai appris cette astuce il y a un moment quand j'ai remarqué la documentation de la fonction scatter --

c : color or sequence of color, optional, default : 'b'

c peut être d'une seule couleur chaîne de format, ou une séquence de couleur spécifications de longueur N, ou une séquence de N nombres à mapper aux couleurs en utilisant le cmap et norm spécifié via kwargs (voir ci-dessous). Notez que c ne doit pas être une séquence numérique RGB ou RGBA, car elle est indiscernable d'un tableau de valeurs à être colormapped. c peut être un tableau 2-D dans lequel les lignes sont RGB ou RGBA, cependant, y compris le cas d'une seule ligne pour spécifier la même couleur pour tous point.

14
répondu vishakad 2016-05-18 12:10:28