Come fare un diagramma a dispersione con cerchi vuoti in Python?


166

In Python, con Matplotlib, come si può tracciare un diagramma a dispersione con cerchi vuoti ? L'obiettivo è disegnare dei cerchi vuoti attorno ad alcuni dei dischi colorati già tracciati da scatter(), in modo da evidenziarli, idealmente senza dover ridisegnare i cerchi colorati.

Ho provato facecolors=None, inutilmente.


1
Le persone che desiderano disegnare grafici a dispersione vuoti / vuoti con colori diversi possono guardare a questa domanda .
ImportanceOfBeingErnest

Risposte:


242

Dalla documentazione per 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

Prova quanto segue:

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

immagine di esempio

Nota: per altri tipi di grafici, vedere questo post sull'uso di markeredgecolore markerfacecolor.


4
Grazie! Il problema è che il più normale (in Python) facecolors=Nonenon funziona, il che mi ha fatto inciampare.
Eric O Lebigot

24
Molto utile. È markerfacecolor='none'così adesso.
hesham_EE,

2
Ho avuto il mio stile matplotlib in un modo che ha impostato la larghezza dei bordi a zero. Se non vedi alcun marker con markerfacecolor='none'prova ad aggiungeremarkeredgewidth=1.0
oLas

Questo approccio può essere utilizzato anche in Seaborn dopo aver effettuato l'importazione standard di Matplotlib %matplotlib inlinee import matplotlib.pyplot as plt, dopo aver impostato Seaborn come impostazione predefinita per la trama diimport seaborn as sns; sns.set()
Jakob,

68

Funzionerebbero?

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

immagine di esempio

o usando plot ()

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

immagine di esempio


3
questo è utile quando lo usi plotinvece discatter
Trevor Boyd Smith

2
Per scatter, è necessario specificare edgecolorscome edgecolors='r'. Altrimenti, i cerchi scompaiono. Vedi qui
T_T

14

Ecco un altro modo: questo aggiunge un cerchio agli assi, alla trama o all'immagine attuali o altro:

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 )

testo alternativo

(I cerchi nella foto vengono schiacciati a ellissi perché imshow aspect="auto").


5

In matplotlib 2.0 è presente un parametro chiamato fillstyle che consente un migliore controllo sulla modalità di riempimento dei marker. Nel mio caso l'ho usato con errorbars ma funziona per i marcatori in generale http://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.errorbar.html

fillstyleaccetta i seguenti valori: ['pieno' | 'sinistra' | "giusto" | 'fondo' | 'top' | 'nessuna']

Ci sono due cose importanti da tenere a mente quando si utilizza fillstyle,

1) Se mfc è impostato su qualsiasi tipo di valore, avrà priorità, quindi, se hai impostato fillstyle su 'none', non avrebbe effetto. Quindi evita di usare mfc in congiunzione con fillstyle

2) Potresti voler controllare la larghezza del bordo del marker (usando markeredgewidtho mew) perché se il marker è relativamente piccolo e la larghezza del bordo è spessa, i marker sembreranno riempiti anche se non lo sono.

Di seguito è riportato un esempio usando errorbars:

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

2

Basati sull'esempio di Gary Kerr e come proposto qui si possono creare cerchi vuoti relativi a valori specificati con il seguente codice:

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

Questa è essenzialmente una versione complessa della risposta accettata ...
Eric O Lebigot,

Dal mio punto non lo è. L'uso del grafico a dispersione con i colori non esclude facecolor = "none" all'interno del comando. Pertanto è necessario il successivo smontaggio del facecolor come descritto nel link indicato. Sfortunatamente questa soluzione complessa è necessaria per rimuovere il facecolor in grafici a dispersione con colorcoding.
Aroc,

L'approccio in questa risposta è davvero utile se si desidera aggiornare un grafico che originariamente non contiene cerchi vuoti. Tuttavia, la domanda sulla creazione di questi cerchi direttamente, quindi la soluzione accettata è la strada da percorrere, poiché fa lo stesso di questa risposta ma direttamente, senza alcun aggiornamento estraneo di un primo grafico.
Eric O Lebigot il

Questa "versione complessa" ha funzionato per me quando l'incorporamento dell'argomento all'interno .scatter()non ha funzionato. Per il contesto, stavo anche applicando una mappa colori ( c=z, cmap='jet').
Andrew Silver,

1

Quindi presumo che tu voglia evidenziare alcuni punti che soddisfano determinati criteri. Puoi usare il comando Prelude per fare un secondo diagramma a dispersione dei punti evidenziati con un cerchio vuoto e una prima chiamata per tracciare tutti i punti. Assicurarsi che il parametro s sia sufficientemente piccolo per consentire ai cerchi vuoti più grandi di racchiudere quelli pieni più piccoli.

L'altra opzione è quella di non usare scatter e disegnare i patch singolarmente usando il comando circle / ellipse. Questi sono in matplotlib.patches, ecco alcuni esempi di codice su come disegnare cerchi rettangoli ecc.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.