Než začneme vykreslovat grafy, je vždy dobré data prozkoumat. Data můžeme načíst do datového rámce pandas a zobrazit prvních 10 řádků:

import pandas as pd# Read in data and examine first 10 rows
flights = pd.read_csv('data/formatted_flights.csv')
flights.head(10)
Hlava datového rámce

Zpoždění příletu je v minutách a záporné hodnoty znamenají, že let byl předčasný (ukazuje se, že lety mají často tendenci přilétat dříve, jen nikdy ne v době, kdy jsme na nich my!) Je zde více než 300 000 letů s minimálním zpožděním -60 minut a maximálním zpožděním 120 minut. Dalším sloupcem v datovém rámci je název letecké společnosti, který můžeme použít pro srovnání.

Skvělým způsobem, jak začít zkoumat jednu proměnnou, je histogram. Histogram rozdělí proměnnou do binů, spočítá datové body v každém binů a na ose x zobrazí biny a na ose y počty. V našem případě budou binem časové intervaly představující zpoždění letů a počtem bude počet letů spadajících do tohoto intervalu. Šířka binů je nejdůležitějším parametrem histogramu a vždy bychom měli vyzkoušet několik různých hodnot šířky binů, abychom vybrali tu nejlepší pro naše data.

Pro vytvoření základního histogramu v Pythonu můžeme použít buď matplotlib, nebo seaborn. Následující kód ukazuje volání funkcí v obou knihovnách, které vytvářejí ekvivalentní obrázky. U volání funkce plot určíme šířku binů počtem binů. Pro tento graf použiji biny o délce 5 minut, což znamená, že počet binů bude odpovídat rozsahu dat (od -60 do 120 minut) děleno šířkou binů, tedy 5 minut ( bins = int(180/5)).

Histogram (ekvivalentní figura vytvořená matplotlibem i seabornem)

Pro většinu základních histogramů, bych zvolil kód matplotlib, protože je jednodušší, ale později budeme používat funkci seaborn distplot pro vytváření různých rozdělení a je dobré se seznámit s různými možnostmi.

Jak jsem přišel na 5 minut pro šířku bin? Jediný způsob, jak zjistit optimální binwidth, je vyzkoušet více hodnot! Níže je uveden kód pro vytvoření stejného obrázku v matplotlib s řadou binwidth. Nakonec neexistuje žádná správná nebo špatná odpověď na šířku bin, ale já jsem zvolil 5 minut, protože si myslím, že nejlépe reprezentuje rozdělení.

Histogramy s různými šířkami bin

Volba šířky bin výrazně ovlivňuje výsledný graf. Menší šířky binů mohou způsobit nepřehlednost grafu, ale větší šířky binů mohou zastřít nuance v datech. Matplotlib za vás automaticky vybere rozumnou šířku binwidth, ale já rád určuji šířku binwidth sám po vyzkoušení několika hodnot. Neexistuje žádná skutečně správná nebo špatná odpověď, takže vyzkoušejte několik možností a zjistěte, která je pro vaše konkrétní data nejvhodnější.

Když histogramy selhávají

Histogramy jsou skvělým způsobem, jak začít zkoumat jednu proměnnou získanou z jedné kategorie. Když však chceme porovnat rozdělení jedné proměnné ve více kategoriích, mají histogramy problémy s čitelností. Chceme-li například porovnat rozdělení zpoždění příletů mezi jednotlivými leteckými společnostmi, přístup, který nefunguje dobře, je vytvořit histogramy pro každou leteckou společnost na stejném grafu:

Překrývající se histogramy s více leteckými společnostmi

(Všimněte si, že osa y byla normalizována, aby se zohlednil rozdílný počet letů mezi leteckými společnostmi. To provedete tak, že volání funkce sns.distplot předáte argument norm_hist = True)

Tento graf není příliš užitečný! Všechny překrývající se sloupce téměř znemožňují porovnání jednotlivých leteckých společností. Podívejme se na několik možných řešení tohoto častého problému.

Řešení č. 1: Histogramy vedle sebe

Místo překrývání histogramů leteckých společností je můžeme umístit vedle sebe. Za tímto účelem vytvoříme seznam zpoždění příletů pro každou leteckou společnost a ten pak předáme do volání funkce plt.hist jako seznam seznamů. Musíme zadat různé barvy, které použijeme pro každou leteckou společnost, a popisek, abychom je mohli od sebe odlišit. Kód včetně vytvoření seznamů pro každou leteckou společnost je uveden níže:

Pokud předáme seznam seznamů, matplotlib standardně umístí sloupce vedle sebe. Zde jsem změnil šířku binů na 15 minut, protože jinak je graf příliš nepřehledný, ale ani s touto úpravou se nejedná o efektivní údaj. Je zde příliš mnoho informací ke zpracování najednou, sloupce nejsou zarovnány se štítky a stále je těžké porovnávat rozložení mezi jednotlivými leteckými společnostmi. Když vytváříme graf, chceme, aby byl pro diváka co nejsnáze pochopitelný, a tento obrázek v tomto kritériu selhává! Podívejme se na druhé možné řešení.

Řešení č. 2: Sloupce na sobě

Místo toho, abychom vykreslovali sloupce pro jednotlivé letecké společnosti vedle sebe, můžeme je poskládat na sebe tak, že volání histogramu předáme parametr stacked = True:

# Stacked histogram with multiple airlines
plt.hist(, bins = int(180/15), stacked=True,
normed=True, color = colors, label=names)

No, to rozhodně není lepší! Zde je každá letecká společnost zastoupena jako výseč celku pro každý koš, ale je téměř nemožné provádět srovnání. Například při zpoždění -15 až 0 minut má větší velikost pruhu společnost United Air Lines nebo JetBlue Airlines? Nedokážu to říct a diváci to také nebudou schopni zjistit. Obecně nejsem zastáncem skládaných sloupců, protože mohou být obtížně interpretovatelné (i když existují případy použití, například při vizualizaci proporcí). Obě řešení, která jsme vyzkoušeli pomocí histogramů, nebyla úspěšná, a tak je čas přejít na graf hustoty.

Hustotní grafy

Nejprve, co je to graf hustoty? Graf hustoty je vyhlazená, spojitá verze histogramu odhadnutá z dat. Nejběžnější forma odhadu je známá jako jádrový odhad hustoty. Při této metodě se v každém jednotlivém datovém bodě vykreslí spojitá křivka (jádro) a všechny tyto křivky se pak sečtou a vytvoří se jeden vyhlazený odhad hustoty. Nejčastěji se používá Gaussovo jádro (které vytváří Gaussovu zvonovou křivku v každém datovém bodě). Pokud se vám stejně jako mně zdá tento popis trochu matoucí, podívejte se na následující graf:

Odhad hustoty jádra (zdroj)

Tady každá malá černá svislá čára na ose x představuje datový bod. Jednotlivá jádra (v tomto příkladu Gaussova) jsou zobrazena nakreslená přerušovanou červenou čarou nad každým bodem. Plná modrá křivka je vytvořena součtem jednotlivých Gaussů a tvoří celkový graf hustoty.

Osa x představuje hodnotu proměnné stejně jako v histogramu, ale co přesně představuje osa y? Osa y v grafu hustoty představuje funkci hustoty pravděpodobnosti pro jádrový odhad hustoty. Musíme si však dát pozor, abychom upřesnili, že se jedná o hustotu pravděpodobnosti, nikoli o pravděpodobnost. Rozdíl je v tom, že hustota pravděpodobnosti je pravděpodobnost na jednotku na ose x. Abychom ji převedli na skutečnou pravděpodobnost, musíme zjistit plochu pod křivkou pro určitý interval na ose x. Poněkud matoucí je, že protože se jedná o hustotu pravděpodobnosti, a nikoli o pravděpodobnost, může osa y nabývat hodnot větších než jedna. Jediným požadavkem na graf hustoty je, aby se celková plocha pod křivkou rovnala jedné. Obecně mám tendenci uvažovat o ose y na grafu hustoty jako o hodnotě pouze pro relativní porovnání různých kategorií.

Hustotní grafy v programu Seaborn

Pro vytvoření hustotních grafů v programu Seaborn můžeme použít buď funkci distplot, nebo kdeplot. Budu nadále používat funkci distplot, protože nám umožňuje vytvořit více rozdělení jedním voláním funkce. Můžeme například vytvořit graf hustoty zobrazující všechna zpoždění příchodů nad odpovídajícím histogramem:

# Density Plot and Histogram of all arrival delays
sns.distplot(flights, hist=True, kde=True,
bins=int(180/5), color = 'darkblue',
hist_kws={'edgecolor':'black'},
kde_kws={'linewidth': 4})

Křivka zobrazuje graf hustoty a histogram pomocí seaborn

Křivka zobrazuje graf hustoty, který je v podstatě hladkou verzí histogramu. Osa y je ve smyslu hustoty a histogram je ve výchozím nastavení normalizován, takže má stejné měřítko y jako graf hustoty.

Analogicky k šířce binů histogramu má graf hustoty parametr zvaný šířka pásma, který mění jednotlivá jádra a výrazně ovlivňuje konečný výsledek grafu. Kreslící knihovna za nás vybere rozumnou hodnotu šířky pásma (ve výchozím nastavení pomocí odhadu ‚scott‘) a na rozdíl od binwidth histogramu obvykle používám výchozí šířku pásma. Můžeme se však podívat na použití různých šířek pásma a zjistit, zda existuje lepší volba. V grafu je ‚scott‘ výchozí, což vypadá jako nejlepší volba.

Hustotní graf zobrazující různé šířky pásma

Všimněte si, že širší šířka pásma vede k většímu vyhlazení rozdělení. Vidíme také, že i když jsme naše data omezili na -60 až 120 minut, graf hustoty přesahuje tyto hranice. To je jeden z možných problémů grafu hustoty: protože vypočítává rozdělení v každém datovém bodě, může generovat data, která se dostanou mimo hranice původních dat. To může znamenat, že na ose x dostaneme nemožné hodnoty, které se v původních datech nikdy nevyskytovaly! Jako poznámku uvádíme, že můžeme také změnit jádro, čímž se změní rozdělení vykreslené v každém bodě dat, a tím i celkové rozdělení. Pro většinu aplikací však výchozí jádro, Gaussovo, a výchozí odhad šířky pásma fungují velmi dobře.

Řešení č. 3 Graf hustoty

Teď, když jsme pochopili, jak se graf hustoty vytváří a co představuje, podívejme se, jak může vyřešit náš problém vizualizace zpoždění příletů více leteckých společností. Abychom mohli zobrazit rozdělení na jednom grafu, můžeme iterovat přes letecké společnosti a pokaždé zavolat distplot s jádrovým odhadem hustoty nastaveným na True a histogramem nastaveným na False. Kód pro vykreslení grafu hustoty s více leteckými společnostmi je následující:

Gustotní graf s více leteckými společnostmi

Konečně jsme dospěli k efektivnímu řešení! Pomocí grafu hustoty můžeme snadno porovnávat jednotlivé letecké společnosti, protože graf je méně nepřehledný. Nyní, když máme konečně k dispozici požadovaný graf, dojdeme k závěru, že všechny tyto letecké společnosti mají téměř totožné rozložení zpoždění příletů! V souboru dat jsou však i další letecké společnosti a my můžeme vykreslit jednu, která je trochu jiná, abychom ilustrovali další volitelný parametr pro grafy hustoty, stínování grafu.

Stínované grafy hustoty

Vyplnění grafu hustoty nám může pomoci rozlišit překrývající se rozdělení. I když to není vždy dobrý přístup, může pomoci zdůraznit rozdíly mezi rozděleními. Pro stínování grafů hustoty předáme ve volání distplot argument shade = True do kde_kws.

sns.distplot(subset, hist = False, kde = True,
kde_kws = {'shade': True, 'linewidth': 3},
label = airline)

Stínovaný graf hustoty

Zda stínovat či nestínovat graf je, stejně jako ostatní možnosti vykreslování, otázka závislá na problému! U tohoto grafu si myslím, že to má smysl, protože stínování nám pomáhá odlišit grafy v oblastech, kde se překrývají. Nyní máme konečně nějaké užitečné informace: Alaska Airlines má tendenci létat dříve než United Airlines. Až budete mít příště na výběr, budete vědět, kterou leteckou společnost si vybrat!“

Kobercové grafy

Pokud chcete zobrazit každou hodnotu v rozdělení a ne jen vyhlazenou hustotu, můžete přidat kobercový graf. Ten zobrazí každý jednotlivý datový bod na ose x, což nám umožní vizualizovat všechny aktuální hodnoty. Výhodou použití nástroje distplot seaborn je, že můžeme přidat kobercový graf pomocí jediného volání parametru rug = True (i s určitým formátováním).

Density Plot with Rug Plot for Alaska Airlines

Při velkém množství datových bodů může být rug plot přeplněný, ale u některých datových sad může být užitečné zobrazit každý datový bod. Kobercový graf nám také umožňuje vidět, jak graf hustoty „vytváří“ data tam, kde žádná neexistují, protože v každém datovém bodě vytváří jádrové rozdělení. Tato rozdělení mohou unikat přes rozsah původních dat a vyvolávat dojem, že společnost Alaska Airlines má zpoždění kratší i delší, než jaká jsou ve skutečnosti zaznamenána. Na tento artefakt hustotních grafů si musíme dávat pozor a upozorňovat na něj diváky!“

Závěry

Tento příspěvek vám snad přiblížil řadu možností vizualizace jedné proměnné z jedné nebo více kategorií. Existuje ještě více jednorozměrných grafů (jedné proměnné), které můžeme vytvořit, například empirické kumulativní grafy hustoty a kvantilové grafy, ale prozatím zůstaneme u histogramů a grafů hustoty (a také kobercových grafů!). Nebojte se, pokud se vám budou zdát možnosti ohromující: s praxí bude správná volba snazší a v případě potřeby můžete vždy požádat o pomoc. Navíc často neexistuje optimální volba a „správné“ rozhodnutí bude záviset na preferencích a cílech vizualizace. Dobré je, že bez ohledu na to, jaký výkres chcete vytvořit, bude existovat způsob, jak to v Pythonu udělat! Vizualizace jsou účinným prostředkem pro sdělování výsledků a znalost všech dostupných možností nám umožní vybrat správný obrázek pro naše data.

Vítám zpětnou vazbu a konstruktivní kritiku a můžete mě kontaktovat na Twitteru @koehrsen_will.

admin

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.

lg