Jak zrobić wykres punktowy z pustymi okręgami w Pythonie?

166

W Pythonie, za pomocą Matplotlib, jak można wykreślić wykres punktowy z pustymi okręgami? Celem jest narysowanie pustych kółek niektórych kolorowych dysków już wykreślonych scatter(), tak aby je podświetlić, najlepiej bez konieczności przerysowywania kolorowych kółek.

Próbowałem facecolors=None, ale bezskutecznie.

Eric O Lebigot
źródło
1
Osoby, które chcą narysować puste / puste wykresy punktowe w różnych kolorach, mogą spojrzeć na to pytanie .
ImportanceOfBeingErnest

Odpowiedzi:

242

Z dokumentacji dla rozpraszania:

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

Spróbuj wykonać następujące czynności:

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

przykładowy obraz

Uwaga: W przypadku innych typów działek zobacz ten post dotyczący używania markeredgecolori markerfacecolor.

Gary Kerr
źródło
4
Dzięki! Problem polega na tym, że bardziej zwyczajny (w Pythonie) facecolors=Nonenie działa, co mnie zaskoczyło.
Eric O Lebigot
24
Bardzo pomocne. To markerfacecolor='none'tak jest teraz.
hesham_EE
2
Mój styl matplotlib ustawiał szerokość krawędzi na zero. Jeśli nie widzisz żadnych znaczników, markerfacecolor='none'spróbuj dodaćmarkeredgewidth=1.0
oLas
Takie podejście może być również stosowany w Seaborn po wykonaniu standardowym import matplotlib %matplotlib inlinei import matplotlib.pyplot as plt, a następnie ustawienie Seaborn być domyślną kreślenia przezimport seaborn as sns; sns.set()
Jakob
68

Czy to zadziała?

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

przykładowy obraz

lub używając plot ()

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

przykładowy obraz

Gökhan Sever
źródło
3
jest to przydatne, gdy używasz plotzamiastscatter
Trevor Boyd Smith
2
Bo scattermusisz określić edgecolorsjak edgecolors='r'. W przeciwnym razie kręgi znikną. Zobacz tutaj
T_T
14

Oto inny sposób: dodaje to okrąg do aktualnych osi, wykresu lub obrazu lub cokolwiek innego:

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 )

tekst alternatywny

(Kręgi na obrazku zostaną zgniecione do elips, ponieważ imshow aspect="auto").

denis
źródło
5

W matplotlib 2.0 istnieje parametr o nazwie, fillstyle który pozwala na lepszą kontrolę nad sposobem wypełniania znaczników. W moim przypadku użyłem go z paskami błędów, ale działa to ogólnie dla znaczników http://matplotlib.org/api/_as_gen/matplotlib.axes.Axes.errorbar.html

fillstyleakceptuje następujące wartości: ['full' | 'lewo' | „w prawo” | „dół” | „do góry” | 'Żaden']

Istnieją dwie ważne rzeczy, o których należy pamiętać podczas używania fillstyle,

1) Jeśli mfc jest ustawione na jakąkolwiek wartość, będzie miało pierwszeństwo, więc jeśli ustawisz styl fillstyle na „none”, nie zadziała. Dlatego unikaj używania mfc w połączeniu z fillstyle

2) Możesz chcieć kontrolować szerokość krawędzi markera (używając markeredgewidthlubmew ), ponieważ jeśli marker jest stosunkowo mały, a szerokość krawędzi jest gruba, markery będą wyglądać na wypełnione, mimo że tak nie jest.

Poniżej znajduje się przykład użycia pasków błędów:

myplot.errorbar(x=myXval, y=myYval, yerr=myYerrVal, fmt='o', fillstyle='none', ecolor='blue',  mec='blue')
Salvatore Cosentino
źródło
2

Bazując na przykładzie Gary'ego Kerra i zgodnie z propozycją tutaj, można utworzyć puste okręgi związane z określonymi wartościami za pomocą następującego kodu:

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
źródło
To jest zasadniczo złożona wersja akceptowanej odpowiedzi…
Eric O Lebigot
Z mojego punktu widzenia tak nie jest. Używanie wykresu punktowego z kolorami nie wyklucza facecolor = "none" w poleceniu. Dlatego konieczne jest późniejsze usunięcie koloru twarzy, jak opisano w podanym linku. Niestety to skomplikowane rozwiązanie jest potrzebne do usunięcia koloru twarzy na wykresach punktowych z kodowaniem kolorami.
Aroc
Podejście w tej odpowiedzi jest rzeczywiście przydatne, jeśli chce się zaktualizować wykres, który pierwotnie nie zawierał pustych okręgów. Jednak pytanie o bezpośrednie tworzenie tych kręgów, więc zaakceptowane rozwiązanie jest drogą do zrobienia, ponieważ robi to samo, co ta odpowiedź, ale bezpośrednio, bez zbędnej aktualizacji pierwszego wykresu.
Eric O Lebigot
Ta „skomplikowana wersja” działała dla mnie, gdy osadzanie argumentu wewnątrz .scatter()nie działało . Dla kontekstu stosowałem również Colormap ( c=z, cmap='jet').
Andrew Silver
1

Zakładam więc, że chcesz podkreślić kilka punktów, które pasują do określonych kryteriów. Możesz użyć polecenia Prelude, aby wykonać drugi wykres punktowy wyróżnionych punktów z pustym okręgiem i pierwsze wywołanie, aby wykreślić wszystkie punkty. Upewnij się, że parametr s jest wystarczająco mały, aby większe puste koła obejmowały mniejsze wypełnione.

Inną opcją jest rezygnacja z rozpraszania i samodzielne rysowanie łat za pomocą polecenia okrąg / elipsa. Są one w matplotlib.patches, tutaj jest przykładowy kod pokazujący, jak rysować koła, prostokąty itp.

whatnick
źródło