2015-02-15 13 views
5

Wykonuję standardowe plansze Matplotlib za pomocą polecenia plt.boxplot(). Moja linia kodu, który tworzy Wykres pudełkowy:Matplotlib boxplot show only max i min flier

bp = plt.boxplot(data, whis=[5, 95], showfliers=True) 

Ponieważ moje dane posiada dużą dystrybucję, otrzymuję dużo ulotek poza zakres wąsów. Aby uzyskać czystszą charakterystykę jakości publikacji, chciałbym pokazać tylko pojedyncze ulotki na maksa. i przy min. wartości danych, zamiast wszystkich ulotek. czy to możliwe? Nie widzę żadnych wbudowanych opcji w dokumentacji, aby to zrobić.

(Mogę ustawić zakres wąsów na maksimum/min, ale to nie jest to, czego chcę, chciałbym zachować wąsy na 5. i 95. percentylu).

Poniżej znajduje się rysunek, nad którym pracuję. Zwróć uwagę na gęstość ulotek. Boxplots

+0

nie jest to, że gęstość ulotek ważna informacja? – tacaswell

+0

Tak, zdecydowanie. Zależy od tego, co próbujesz pokazać, jak przypuszczam. Ale robisz dobry punkt. – PJW

Odpowiedz

3

plt.boxplot() zwraca słownik, w którym klucz fliers zawiera górny i dolny lotnik jako obiekty line2d. Można manipulować nimi przed kreślenia tak:

Tylko na matplotlib> = 1.4.0

bp = plt.boxplot(data, whis=[5, 95], showfliers=True) 

# Get a list of Line2D objects, representing a single line from the 
# minimum to the maximum flier points. 
fliers = bp['fliers'] 

# Iterate over it! 
for fly in fliers: 
    fdata = fly.get_data() 
    fly.set_data([fdata[0][0],fdata[0][-1]],[fdata[1][0],fdata[1][-1]]) 

W starszych wersjach

Jeśli jesteś w starszej wersji matplotlib The ulotki dla każdego pudełka są reprezentowane przez linie dwie linie, a nie jedną. Zatem, pętla będzie wyglądać mniej więcej tak:

import numpy as np 
for i in range(len(fliers)): 
    fdata = fliers[i].get_data() 
    # Get the index of the maximum y in data if 
    # i is 0 or even, else get index of minimum y. 
    if i%2 == 0: 
     id = np.where(fdata[1] == fdata[1].max())[0][0] 
    else: 
     id = np.where(fdata[1] == fdata[1].min())[0][0] 
    fliers[i].set_data([fdata[0][id], fdata[1][id]]) 

Należy również pamiętać, że showfliers argument nie istnieje w matplotlib < 1.4x oraz whisk argumentem nie akceptuje list.

Oczywiście (dla prostych aplikacji) można wykreślić Wykres pudełkowy bez ulotki i dodaj max i min punkty do działki:

bp = plt.boxplot(data, whis=[5, 95], showfliers=False) 
sc = plt.scatter([1, 1], [data.min(), data.max()]) 

gdzie [1, 1] Czy X-położenie punktów.

+0

Twoje pierwsze rozwiązanie kreśli wszystkich najlepszych, ale nie min. Jeśli podasz w min dla max w kodzie, to po prostu działka min. Może czegoś mi brakuje, ale jak mam uzyskać zarówno maksymalną, jak i minimalną wartość do wykreślenia? Drugie sugerowane rozwiązanie nie działa .... wyświetla niektóre punkty poniżej pól, ale nie są to miny. Trzecie sugerowane rozwiązanie nie będzie dla mnie działało, ponieważ "dane" są w rzeczywistości listą wielu ramek danych Pandy (tworzących wiele wykresów na pudełku, jak na zamieszczonym rysunku). Dziękuję za odpowiedź, myślę, że jest bardzo blisko! – PJW

+0

Przepraszam, wczoraj było trochę za późno. Naprawiłem to powyżej. Mam nadzieję, że jest to dość jednoznaczne i łatwe do naśladowania. Wyciągnęliśmy także drugą sugestię. – Geotob

+0

Teraz min i maksimum na przemian, tak, że pole 1 pokazuje tylko maksimum, pole 2 pokazuje tylko min, pole 3 pokazuje tylko maksimum, itd ......? Zobacz rysunek, który dodałem powyżej. – PJW

1
fliers = bp['fliers'] 
for i in range(len(fliers)): # iterate through the Line2D objects for the fliers for each boxplot 
    box = fliers[i] # this accesses the x and y vectors for the fliers for each box 
    box.set_data([[box.get_xdata()[0],box.get_xdata()[0]],[np.min(box.get_ydata()),‌​np.max(box.get_ydata())]]) 
    # note that you can use any two values from the xdata vector 

Wynikające postać, pokazując tylko max i min ulotki: enter image description here

Powiązane problemy