Comment faire un nuage de points avec des cercles vides en Python?

168

En Python, avec Matplotlib, comment tracer un nuage de points avec des cercles vides ? Le but est de dessiner des cercles vides autour de certains des disques colorés déjà tracés parscatter() , de manière à les mettre en évidence, idéalement sans avoir à redessiner les cercles colorés.

J'ai essayé facecolors=None, en vain.

Eric O Lebigot
la source
1
Les personnes qui cherchent à dessiner des nuages ​​de points vides / creux de différentes couleurs peuvent se pencher sur cette question .
ImportanceOfBeingErnest

Réponses:

244

De la documentation pour scatter:

Optional kwargs control the Collection properties; in particular:

    edgecolors:
        The string none to plot faces with no outlines
    facecolors:
        The string none to plot unfilled outlines

Essayez ce qui suit:

import matplotlib.pyplot as plt 
import numpy as np 

x = np.random.randn(60) 
y = np.random.randn(60)

plt.scatter(x, y, s=80, facecolors='none', edgecolors='r')
plt.show()

image d'exemple

Remarque: pour d'autres types de graphiques, consultez cet article sur l'utilisation de markeredgecoloret markerfacecolor.

Gary Kerr
la source
4
Merci! Le problème est que le plus habituel (en Python) facecolors=Nonene fonctionne pas, ce qui m'a trébuché.
Eric O Lebigot
24
Très utile. C'est markerfacecolor='none', c'est comme ça maintenant.
hesham_EE
2
J'ai eu mon style matplotlib d'une manière qui définissait les largeurs des bords à zéro. Si vous ne voyez aucun marqueur avec markerfacecolor='none'essayez d'ajoutermarkeredgewidth=1.0
oLas
Cette approche peut également être utilisée dans Seaborn après avoir effectué l'importation standard de Matplotlib %matplotlib inlineet import matplotlib.pyplot as plt, puis en définissant Seaborn comme le traçage par défaut parimport seaborn as sns; sns.set()
Jakob
68

Cela fonctionnerait-il?

plt.scatter(np.random.randn(100), np.random.randn(100), facecolors='none')

image d'exemple

ou en utilisant plot ()

plt.plot(np.random.randn(100), np.random.randn(100), 'o', mfc='none')

image d'exemple

Gökhan Sever
la source
3
ceci est utile lorsque vous utilisez à la plotplace descatter
Trevor Boyd Smith
2
Pour scatter, vous devez spécifier edgecolorscomme edgecolors='r'. Sinon, les cercles disparaissent. Voir ici
T_T
14

Voici une autre façon: cela ajoute un cercle aux axes, au tracé ou à l'image actuels ou autre:

from matplotlib.patches import Circle  # $matplotlib/patches.py

def circle( xy, radius, color="lightsteelblue", facecolor="none", alpha=1, ax=None ):
    """ add a circle to ax= or current axes
    """
        # from .../pylab_examples/ellipse_demo.py
    e = Circle( xy=xy, radius=radius )
    if ax is None:
        ax = pl.gca()  # ax = subplot( 1,1,1 )
    ax.add_artist(e)
    e.set_clip_box(ax.bbox)
    e.set_edgecolor( color )
    e.set_facecolor( facecolor )  # "none" not None
    e.set_alpha( alpha )

texte alternatif

(Les cercles dans l'image sont écrasés en ellipses parce que imshow aspect="auto").

denis
la source
5

Dans matplotlib 2.0, il existe un paramètre appelé fillstyle qui permet un meilleur contrôle sur la façon dont les marqueurs sont remplis. Dans mon cas, je l'ai utilisé avec des barres d'erreur mais cela fonctionne pour les marqueurs en général http://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.errorbar.html

fillstyleaccepte les valeurs suivantes: ['full' | «gauche» | «droite» | «bas» | «top» | 'aucun']

Il y a deux choses importantes à garder à l'esprit lors de l'utilisation fillstyle ,

1) Si mfc est défini sur n'importe quel type de valeur, il sera prioritaire, par conséquent, si vous définissez fillstyle sur 'none', cela ne prendrait pas effet. Évitez donc d'utiliser mfc en conjonction avec fillstyle

2) Vous pouvez contrôler la largeur du bord du marqueur (en utilisant markeredgewidthoumew ) car si le marqueur est relativement petit et la largeur du bord est épaisse, les marqueurs auront l'air remplis même s'ils ne le sont pas.

Voici un exemple utilisant des barres d'erreurs:

myplot.errorbar(x=myXval, y=myYval, yerr=myYerrVal, fmt='o', fillstyle='none', ecolor='blue',  mec='blue')
Salvatore Cosentino
la source
2

Basez-vous sur l'exemple de Gary Kerr et comme proposé ici, on peut créer des cercles vides liés à des valeurs spécifiées avec le code suivant:

import matplotlib.pyplot as plt 
import numpy as np 
from matplotlib.markers import MarkerStyle

x = np.random.randn(60) 
y = np.random.randn(60)
z = np.random.randn(60)

g=plt.scatter(x, y, s=80, c=z)
g.set_facecolor('none')
plt.colorbar()
plt.show()
Aroc
la source
C'est la version essentiellement complexifiée de la réponse acceptée…
Eric O Lebigot
De mon point de vue n'est-ce pas. L'utilisation d'un nuage de points avec des couleurs n'exclut pas facecolor = "none" dans la commande. Pour cela, le retrait ultérieur de la couleur faciale est nécessaire comme décrit dans le lien donné. Malheureusement, cette solution complexifiée est nécessaire pour éliminer la couleur du visage dans les nuages ​​de points avec codage couleur.
Aroc
L'approche de cette réponse est en effet utile si l'on veut mettre à jour un graphe qui à l'origine ne contient pas de cercles vides. Cependant, la question de créer ces cercles directement, donc la solution acceptée est la voie à suivre, car elle fait la même chose que cette réponse mais directement, sans mise à jour superflue d'un premier graphique.
Eric O Lebigot
Cette «version complexifiée» a fonctionné pour moi lorsque l'incorporation de l'argument à l'intérieur .scatter()n'a pas fonctionné. Pour le contexte, j'appliquais également une palette de couleurs ( c=z, cmap='jet').
Andrew Silver
1

Je suppose donc que vous voulez souligner certains points qui correspondent à certains critères. Vous pouvez utiliser la commande de Prelude pour faire un deuxième nuage de points des points surlignés avec un cercle vide et un premier appel pour tracer tous les points. Assurez-vous que le paramètre s est suffisamment petit pour que les plus grands cercles vides entourent les plus petits remplis.

L'autre option consiste à ne pas utiliser de dispersion et à dessiner les patchs individuellement à l'aide de la commande cercle / ellipse. Ceux-ci sont dans matplotlib.patches, voici un exemple de code sur la façon de dessiner des rectangles de cercles, etc.

whatnick
la source