Aby narysować wykres w polu przy użyciu tylko wartości percentyla i wartości odstających (jeśli istnieją), wykonałem funkcję customized_box_plot
, która zasadniczo modyfikuje atrybuty na podstawowym wykresie pudełkowym (wygenerowanym z niewielkich próbek danych), aby dopasować go do wartości percentyla.
customized_box_plot
funkcja
def customized_box_plot(percentiles, axes, redraw = True, *args, **kwargs):
"""
Generates a customized boxplot based on the given percentile values
"""
box_plot = axes.boxplot([[-9, -4, 2, 4, 9],]*n_box, *args, **kwargs)
# Creates len(percentiles) no of box plots
min_y, max_y = float('inf'), -float('inf')
for box_no, (q1_start,
q2_start,
q3_start,
q4_start,
q4_end,
fliers_xy) in enumerate(percentiles):
# Lower cap
box_plot['caps'][2*box_no].set_ydata([q1_start, q1_start])
# xdata is determined by the width of the box plot
# Lower whiskers
box_plot['whiskers'][2*box_no].set_ydata([q1_start, q2_start])
# Higher cap
box_plot['caps'][2*box_no + 1].set_ydata([q4_end, q4_end])
# Higher whiskers
box_plot['whiskers'][2*box_no + 1].set_ydata([q4_start, q4_end])
# Box
box_plot['boxes'][box_no].set_ydata([q2_start,
q2_start,
q4_start,
q4_start,
q2_start])
# Median
box_plot['medians'][box_no].set_ydata([q3_start, q3_start])
# Outliers
if fliers_xy is not None and len(fliers_xy[0]) != 0:
# If outliers exist
box_plot['fliers'][box_no].set(xdata = fliers_xy[0],
ydata = fliers_xy[1])
min_y = min(q1_start, min_y, fliers_xy[1].min())
max_y = max(q4_end, max_y, fliers_xy[1].max())
else:
min_y = min(q1_start, min_y)
max_y = max(q4_end, max_y)
# The y axis is rescaled to fit the new box plot completely with 10%
# of the maximum value at both ends
axes.set_ylim([min_y*1.1, max_y*1.1])
# If redraw is set to true, the canvas is updated.
if redraw:
ax.figure.canvas.draw()
return box_plot
ZASTOSOWANIE
pomocą logiki odwrotnej (kod na samym końcu) I ekstrahuje wartości percentyla z tego example
>>> percentiles
(-1.0597368367634488, 0.3977683984966961, 1.0298955252405229, 1.6693981537742526, 3.4951447843464449)
(-0.90494930553559483, 0.36916539612108634, 1.0303658700697103, 1.6874542731392828, 3.4951447843464449)
(0.13744105279440233, 1.3300645202649739, 2.6131540656339483, 4.8763411136047647, 9.5751914834437937)
(0.22786243898199182, 1.4120860286080519, 2.637650402506837, 4.9067126578493259, 9.4660357513550899)
(0.0064696168078617741, 0.30586770128093388, 0.70774153557312702, 1.5241965711101928, 3.3092932063051976)
(0.007009744579241136, 0.28627373934008982, 0.66039691869500572, 1.4772725266672091, 3.221716765477217)
(-2.2621660374110544, 5.1901313713883352, 7.7178532139979357, 11.277744848353247, 20.155971739152388)
(-2.2621660374110544, 5.1884411864079532, 7.3357079047721054, 10.792299385806913, 18.842012119715388)
(2.5417888074435702, 5.885996170695587, 7.7271286220368598, 8.9207423361593179, 10.846938621419374)
(2.5971767318505856, 5.753551925927133, 7.6569980004033464, 8.8161056254143233, 10.846938621419374)
Należy zauważyć, że aby to krótko nie pokazałem o wektory utliers, które będą szóstym elementem każdej z tablic percentyla.
Należy również pamiętać, że wszystkie zwykłe dodatkowe kwargs/args może być stosowany, ponieważ są one po prostu przekazywane do metody boxplot
wewnątrz niego:
>>> fig, ax = plt.subplots()
>>> b = customized_box_plot(percentiles, ax, redraw=True, notch=0, sym='+', vert=1, whis=1.5)
>>> plt.show()

wyjaśnienie
Metoda boxplot
zwraca słownik mapujący komponenty boxplot na poszczególne instancje matplotlib.lines.Line2D
zostały stworzone.
Cytując z dokumentacji matplotlib.pyplot.boxplot
:
Ten słownik zawiera następujące klucze (zakładając pionowe boxplots):
pudełka: główny korpus boxplot przedstawiający kwartyle i przedziały ufności mediana, jeżeli włączona .
mediany: linie horyzontalne na środkowej stronie każdego pola.
wąsy: pionowe linie rozciągające się do najbardziej ekstremalnych, n-mniejszych punktów danych. czapki: poziome linie na końcach wąsów.
ulotki: punkty reprezentujące dane wykraczające poza wąsy (wartości odstające).
oznacza: punkty lub linie reprezentujące środki.
Na przykład obserwować boxplot
z maleńkim danych próbka [-9, -4, 2, 4, 9]
>>> b = ax.boxplot([[-9, -4, 2, 4, 9],])
>>> b
{'boxes': [<matplotlib.lines.Line2D at 0x7fe1f5b21350>],
'caps': [<matplotlib.lines.Line2D at 0x7fe1f54d4e50>,
<matplotlib.lines.Line2D at 0x7fe1f54d0e50>],
'fliers': [<matplotlib.lines.Line2D at 0x7fe1f5b317d0>],
'means': [],
'medians': [<matplotlib.lines.Line2D at 0x7fe1f63549d0>],
'whiskers': [<matplotlib.lines.Line2D at 0x7fe1f5b22e10>,
<matplotlib.lines.Line2D at 0x7fe20c54a510>]}
>>> plt.show()

W matplotlib.lines.Line2D
obiekty mają dwie metody, które będę w moim użyciu funkcji obszernie. set_xdata
(lub set_ydata
) i get_xdata
(lub).
Korzystając z tych metod, możemy zmienić położenie linii składowych wykresu skrzynki bazowej, aby dostosować je do wartości percentyla (co robi funkcja customized_box_plot
). Po zmieniając pozycję Linie składnika, można przerysować płótno używając figure.canvas.draw()
Podsumowując mapowania z percentyla do współrzędnych różnych Line2D
obiektów.
współrzędne Y:
- Maksymalna (
q4_end
- koniec 4 kwartyl) odpowiada skrajnym górnym pokrywy Line2D
obiektu.
- Min (
q1_start
- początek pierwszego kwartylu) odpowiada najniższemu z najwyższych limitów obiektów Line2D
.
- Mediana odpowiada medianie (
q3_start
) obiektu Line2D
.
- W 2 wąsy znajdować się pomiędzy końcami skrzyń i skrajne kapsle (
q1_start
i q2_start
- niższe bokobrody; q4_start
i q4_end
- górna whisker)
- pudełko jest rzeczywiście interesujące
n
kształcie linii ograniczony kołpakiem w dolną część. Ekstremalne linie w kształcie n
odpowiadają q2_start
i q4_start
.
X Współrzędne
- Centralny współrzędne x (dla wielu wykresów skrzynkowych są zazwyczaj 1, 2, 3 ...)
- Biblioteka automatycznie oblicza współrzędne x ograniczająca oparta na określona szerokość.
funkcja odwrotna do pobierania percentyla OD DICT boxplot:
def get_percentiles_from_box_plots(bp):
percentiles = []
for i in range(len(bp['boxes'])):
percentiles.append((bp['caps'][2*i].get_ydata()[0],
bp['boxes'][i].get_ydata()[0],
bp['medians'][i].get_ydata()[0],
bp['boxes'][i].get_ydata()[2],
bp['caps'][2*i + 1].get_ydata()[0],
(bp['fliers'][i].get_xdata(),
bp['fliers'][i].get_ydata())))
return percentiles
UWAGA: Powodem, dlaczego nie zrobić to metoda całkowicie niestandardowe boxplot dlatego istnieje wiele funkcji oferowanych przez wbudowany okno dialogowe, którego nie można w pełni odtworzyć.
wybaczcie Także jeśli mogę mieć niepotrzebnie wyjaśnić coś, co może być zbyt oczywiste.
Su ggestion: czy mógłbyś przedstawić problem w sposób abstrakcyjny? Oznacza to, że zamiast mówić "latencje" użyj jakiejś abstrakcji. "Zmierzyłem pewne rzeczywiste wartości, tj. Zmiennoprzecinkowe, i chciałbym obliczyć percentyle ...". – polarise