¿Cómo hacer un diagrama de dispersión con círculos vacíos en Python?


166

En Python, con Matplotlib, ¿cómo se puede trazar un diagrama de dispersión con círculos vacíos ? El objetivo es dibujar círculos vacíos alrededor de algunos de los discos de colores ya trazados scatter(), para resaltarlos, idealmente sin tener que volver a dibujar los círculos de colores.

Lo intenté facecolors=None, pero fue en vano.


1
Las personas que buscan dibujar diagramas de dispersión vacíos / huecos con diferentes colores pueden considerar esta pregunta .
ImportanceOfBeingErnest

Respuestas:


242

De la documentación para dispersión:

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

Intenta lo siguiente:

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()

imagen de ejemplo

Nota: Para otros tipos de parcelas, vea esta publicación sobre el uso de markeredgecolory markerfacecolor.


44
¡Gracias! El problema es que lo más habitual (en Python) facecolors=Noneno funciona, lo que me hizo tropezar.
Eric O Lebigot

24
Muy útil. Es markerfacecolor='none', así es ahora.
hesham_EE

2
Tenía mi estilo matplotlib de una manera que ajustaba el ancho de los bordes a cero. Si no ve ningún marcador con markerfacecolor='none'intente agregarmarkeredgewidth=1.0
oLas

Este enfoque también se puede usar en Seaborn después de realizar la importación estándar de Matplotlib %matplotlib inliney import matplotlib.pyplot as plt, luego, configurar Seaborn para que sea el trazado predeterminado porimport seaborn as sns; sns.set()
Jakob el

68

¿Funcionarían estos?

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

imagen de ejemplo

o usando plot ()

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

imagen de ejemplo


3
Esto es útil para cuando se usa en plotlugar descatter
Trevor Boyd Smith

2
Para scatter, debe especificar edgecolorscomo edgecolors='r'. De lo contrario, los círculos desaparecen. Ver aquí
T_T

14

Aquí hay otra forma: esto agrega un círculo a los ejes actuales, la trama o la imagen o lo que sea:

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 )

texto alternativo

(Los círculos en la imagen se convierten en elipses porque imshow aspect="auto").


5

En matplotlib 2.0 hay un parámetro llamado fillstyle que permite un mejor control sobre la forma en que se llenan los marcadores. En mi caso lo he usado con barras de error pero funciona para marcadores en general http://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.errorbar.html

fillstyleacepta los siguientes valores: ['full' | 'izquierda' | 'derecho' | 'fondo' | 'top' | 'ninguna']

Hay dos cosas importantes a tener en cuenta al usar fillstyle,

1) Si mfc se establece en cualquier tipo de valor, tendrá prioridad, por lo tanto, si configuró el estilo de relleno en 'ninguno', no tendría efecto. Así que evite usar mfc en conjunción con el estilo de relleno

2) Es posible que desee controlar el ancho del borde del marcador (usando markeredgewidtho mew) porque si el marcador es relativamente pequeño y el ancho del borde es grueso, los marcadores se verán rellenos aunque no lo estén.

El siguiente es un ejemplo usando barras de error:

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

2

Basándose en el ejemplo de Gary Kerr y como se propone aquí, uno puede crear círculos vacíos relacionados con valores especificados con el siguiente código:

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()

Esta es esencialmente una versión compleja, la respuesta aceptada ...
Eric O Lebigot 02 de

Desde mi punto no lo es. El uso del diagrama de dispersión con colores no incluye facecolor = "none" dentro del comando. Por lo tanto, la eliminación posterior del color de la cara es necesaria como se describe en el enlace dado. Desafortunadamente, esta solución compleja es necesaria para eliminar el color de la cara en diagramas de dispersión con codificación de color.
Aroc

El enfoque en esta respuesta es realmente útil si uno quiere actualizar un gráfico que originalmente no contiene círculos vacíos. Sin embargo, la pregunta sobre la creación de estos círculos directamente, por lo que la solución aceptada es el camino a seguir, ya que hace lo mismo que esta respuesta pero directamente, sin una actualización extraña de un primer gráfico.
Eric O Lebigot

Esta "versión compleja" funcionó para mí cuando incrustar el argumento dentro .scatter()no lo hizo. Por contexto, también estaba aplicando un mapa de colores ( c=z, cmap='jet').
Andrew Silver

1

Así que supongo que desea resaltar algunos puntos que se ajustan a ciertos criterios. Puede usar el comando Prelude para hacer un segundo diagrama de dispersión de los puntos resaltados con un círculo vacío y una primera llamada para trazar todos los puntos. Asegúrese de que el parámetro s sea lo suficientemente pequeño para que los círculos vacíos más grandes encierren los más pequeños llenos.

La otra opción es no usar dispersión y dibujar los parches individualmente usando el comando circle / ellipse. Estos están en matplotlib.patches, aquí hay un código de muestra sobre cómo dibujar círculos, rectángulos, etc.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.