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)
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)
).
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í.
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:
(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:
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})