Het is altijd een goed idee om onze data te onderzoeken voordat we beginnen met plotten. We kunnen de data inlezen in een pandas dataframe en de eerste 10 rijen weergeven:

import pandas as pd# Read in data and examine first 10 rows
flights = pd.read_csv('data/formatted_flights.csv')
flights.head(10)
Hoofd van dataframe

De vluchtvertragingen zijn in minuten en negatieve waarden betekenen dat de vlucht te vroeg aankwam (het blijkt dat vluchten vaak te vroeg aankomen, alleen nooit als wij er op zitten!) Er zijn meer dan 300.000 vluchten met een minimumvertraging van -60 minuten en een maximumvertraging van 120 minuten. De andere kolom in het dataframe is de naam van de luchtvaartmaatschappij, die we kunnen gebruiken voor vergelijkingen.

Een geweldige manier om te beginnen met het verkennen van een enkele variabele is met het histogram. Een histogram verdeelt de variabele in bins, telt de datapunten in elke bin, en toont de bins op de x-as en de tellingen op de y-as. In ons geval zijn de bins een tijdsinterval dat de vertraging van de vluchten weergeeft en de telling het aantal vluchten dat in dat interval valt. De binbreedte is de belangrijkste parameter voor een histogram en we moeten altijd een paar verschillende waarden van binbreedte uitproberen om de beste voor onze gegevens te selecteren.

Om een basis histogram in Python te maken, kunnen we matplotlib of seaborn gebruiken. De code hieronder toont functie-aanroepen in beide bibliotheken die gelijkwaardige figuren maken. Voor de aanroepen tot plot specificeren we de binbreedte door het aantal bins. Voor deze plot gebruik ik bins van 5 minuten lengte, wat betekent dat het aantal bins gelijk is aan het bereik van de gegevens (van -60 tot 120 minuten) gedeeld door de binbreedte, 5 minuten ( bins = int(180/5)).

Histogram (equivalent berekend door zowel matplotlib als seaborn)

Voor de meeste basis histogrammen, zou ik voor de matplotlib-code kiezen omdat deze eenvoudiger is, maar we zullen de seaborn distplot-functie later gebruiken om verschillende verdelingen te maken en het is goed om vertrouwd te zijn met de verschillende opties.

Hoe kwam ik op 5 minuten voor de binbreedte? De enige manier om de optimale binbreedte te bepalen is door meerdere waarden uit te proberen! Hieronder staat code om dezelfde figuur in matplotlib te maken met een reeks binwidths. Uiteindelijk is er geen goed of fout antwoord op de binbreedte, maar ik kies voor 5 minuten omdat ik denk dat dit de verdeling het beste weergeeft.

Histogrammen met verschillende binbreedtes

De keuze van de binbreedte heeft een grote invloed op de resulterende plot. Kleinere binbreedtes kunnen de plot onoverzichtelijk maken, maar grotere binbreedtes kunnen nuances in de gegevens verdoezelen. Matplotlib zal automatisch een redelijke binbreedte voor u kiezen, maar ik geef de binbreedte graag zelf op nadat ik verschillende waarden heb uitgeprobeerd. Er is geen echt goed of fout antwoord, dus probeer een paar opties en kijk welke het beste werkt voor uw specifieke gegevens.

Wanneer Histogrammen falen

Histogrammen zijn een geweldige manier om te beginnen met het verkennen van een enkele variabele uit één categorie. Wanneer we echter de verdeling van een variabele over meerdere categorieën willen vergelijken, hebben histogrammen problemen met de leesbaarheid. Als wij bijvoorbeeld de verdelingen van de aankomstvertragingen tussen luchtvaartmaatschappijen willen vergelijken, is een aanpak die niet goed werkt het maken van histogrammen voor elke luchtvaartmaatschappij op dezelfde plot:

Overlappende histogrammen met meerdere luchtvaartmaatschappijen

(Merk op dat de y-as is genormaliseerd om rekening te houden met het verschil in aantal vluchten tussen luchtvaartmaatschappijen. Geef hiervoor het argument norm_hist = True door aan de functie-oproep sns.distplot.)

Deze plot is niet erg nuttig! Alle overlappende balken maken het bijna onmogelijk om vergelijkingen tussen de luchtvaartmaatschappijen te maken. Laten we eens kijken naar een paar mogelijke oplossingen voor dit veel voorkomende probleem.

Oplossing #1: Histogrammen naast elkaar

In plaats van de histogrammen van de luchtvaartmaatschappijen te laten overlappen, kunnen we ze ook naast elkaar plaatsen. Om dit te doen, maken wij een lijst van de aankomstvertragingen voor elke luchtvaartmaatschappij, en geven deze dan door aan de plt.hist functie-aanroep als een lijst van lijsten. We moeten verschillende kleuren opgeven voor elke luchtvaartmaatschappij en een label, zodat we ze uit elkaar kunnen houden. De code, inclusief het maken van de lijsten voor elke luchtvaartmaatschappij, staat hieronder:

Als we standaard een lijst met lijsten invoeren, zet matplotlib de balken naast elkaar. Hier heb ik de binbreedte gewijzigd in 15 minuten omdat de plot anders te onoverzichtelijk wordt, maar zelfs met deze wijziging is dit geen effectieve figuur. Er is te veel informatie om in één keer te verwerken, de staven liggen niet op één lijn met de labels, en het is nog steeds moeilijk om de verdelingen tussen de luchtvaartmaatschappijen te vergelijken. Als we een diagram maken, willen we dat het voor de kijker zo gemakkelijk mogelijk te begrijpen is, en deze figuur voldoet niet aan dat criterium! Laten we eens kijken naar een tweede mogelijke oplossing.

Oplossing #2: Gestapelde balken

In plaats van de balken voor elke luchtvaartmaatschappij naast elkaar uit te zetten, kunnen we ze stapelen door de parameter stacked = True door te geven aan de histogram-oproep:

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

Wel, dat is zeker niet beter! Hier wordt elke luchtvaartmaatschappij weergegeven als een deel van het geheel voor elke bin, maar het is bijna onmogelijk om vergelijkingen te maken. Bijvoorbeeld, bij een vertraging van -15 tot 0 minuten, heeft United Air Lines of JetBlue Airlines een grotere omvang van de balk? Ik kan het niet zien en de kijkers zullen het ook niet kunnen zien. Ik ben over het algemeen geen voorstander van gestapelde balken omdat ze moeilijk te interpreteren zijn (hoewel er toepassingen zijn zoals bij het visualiseren van verhoudingen). Beide oplossingen die we met histogrammen hebben geprobeerd, waren geen succes, en dus is het tijd om over te stappen op de dichtheidsplot.

Dichtheidsplots

Voreerst, wat is een dichtheidsplot? Een dichtheidsplot is een afgevlakte, continue versie van een histogram dat op basis van de gegevens wordt geschat. De meest gebruikelijke vorm van schatting staat bekend als kernel density estimation. Bij deze methode wordt voor elk gegevenspunt een continue kromme (de kernel) getekend en worden al deze krommen vervolgens bij elkaar opgeteld om tot één gladde dichtheidsschatting te komen. De meest gebruikte kernel is een Gaussische (die in elk gegevenspunt een Gaussische belcurve oplevert). Als u, net als ik, deze beschrijving een beetje verwarrend vindt, kijk dan eens naar de volgende plot:

Kernel Density Estimation (Bron)

Hier stelt elk klein zwart verticaal lijntje op de x-as een gegevenspunt voor. De afzonderlijke kernels (Gaussians in dit voorbeeld) worden weergegeven in gestippelde rode lijnen boven elk punt. De ononderbroken blauwe kromme ontstaat door de som van de afzonderlijke Gaussians en vormt de totale dichtheidsplot.

De x-as is de waarde van de variabele, net als in een histogram, maar wat stelt de y-as precies voor? De y-as in een dichtheidsplot is de kansdichtheidsfunctie voor de kernel dichtheidsschatting. We moeten echter voorzichtig zijn om te specificeren dat dit een waarschijnlijkheidsdichtheid is en niet een waarschijnlijkheid. Het verschil is dat de kansdichtheid de kans per eenheid op de x-as is. Om dit om te zetten in een reële kans, moeten wij het gebied onder de curve vinden voor een bepaald interval op de x-as. Enigszins verwarrend is dat, omdat dit een waarschijnlijkheidsdichtheid is en geen waarschijnlijkheid, de y-as waarden groter dan één kan aannemen. De enige vereiste van de dichtheidsplot is dat het totale gebied onder de kromme integreert tot één. Ik ben over het algemeen geneigd om de y-as op een dichtheidsplot alleen te zien als een waarde voor relatieve vergelijkingen tussen verschillende categorieën.

Dichtheidsplots in Seaborn

Om dichtheidsplots in seaborn te maken, kunnen we ofwel de distplot of kdeplot functie gebruiken. Ik zal de distplot functie blijven gebruiken, omdat het ons in staat stelt om meerdere verdelingen te maken met één functie-aanroep. We kunnen bijvoorbeeld een dichtheidsplot maken met alle aankomstvertragingen bovenop het bijbehorende histogram:

# 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})

Dichtheidsplot en histogram met seaborn

De curve toont de dichtheidsplot die in wezen een vloeiende versie van het histogram is. De y-as is in termen van dichtheid, en het histogram is standaard genormaliseerd zodat het dezelfde y-schaal heeft als de dichtheidsplot.

Analoog aan de binbreedte van een histogram, heeft een dichtheidsplot een parameter genaamd de bandbreedte die de individuele kernels verandert en het eindresultaat van de plot aanzienlijk beïnvloedt. De plotbibliotheek zal een redelijke waarde van de bandbreedte voor ons kiezen (standaard met de ‘scott’ schatting), en in tegenstelling tot de binbreedte van een histogram, gebruik ik meestal de standaard bandbreedte. We kunnen echter het gebruik van verschillende bandbreedtes bekijken om te zien of er een betere keuze is. In de grafiek is ‘scott’ de standaard, wat de beste optie lijkt.

Density Plot Showing different Bandwidths

Merk op dat een bredere bandbreedte resulteert in meer afvlakking van de verdeling. We zien ook dat, hoewel we onze gegevens hebben beperkt tot -60 tot 120 minuten, de dichtheidsplot zich tot buiten deze grenzen uitstrekt. Dit is een potentieel probleem met een dichtheidsplot: omdat hij op elk gegevenspunt een verdeling berekent, kan hij gegevens genereren die buiten de grenzen van de oorspronkelijke gegevens vallen. Dit kan betekenen dat we onmogelijke waarden op de x-as krijgen die nooit in de oorspronkelijke gegevens voorkwamen! We kunnen ook de kernel veranderen, waardoor de verdeling in elk gegevenspunt verandert en dus ook de algemene verdeling. Voor de meeste toepassingen werken de standaard kernel, Gaussian, en de standaard bandbreedte-schatting echter heel goed.

Oplossing #3 Density Plot

Nu we begrijpen hoe een density plot wordt gemaakt en wat het voorstelt, laten we eens kijken hoe het ons probleem kan oplossen van het visualiseren van de aankomstvertragingen van meerdere luchtvaartmaatschappijen. Om de verdelingen op dezelfde plot te tonen, kunnen we de luchtvaartmaatschappijen itereren, waarbij we telkens distplot aanroepen met de kernel density estimate op True en het histogram op False. De code om de dichtheidsplot met meerdere luchtvaartmaatschappijen te tekenen staat hieronder:

Dichtheidsplot met meerdere luchtvaartmaatschappijen

Eindelijk hebben we een effectieve oplossing gevonden! Met de dichtheidsplot kunnen we gemakkelijk vergelijkingen maken tussen luchtvaartmaatschappijen omdat de plot minder onoverzichtelijk is. Nu we eindelijk de plot hebben die we willen, komen we tot de conclusie dat al deze luchtvaartmaatschappijen bijna identieke verdelingen van de aankomstvertraging hebben! Er zijn echter nog meer luchtvaartmaatschappijen in de dataset, en we kunnen er een plotten die een beetje anders is om een andere optionele parameter voor dichtheidsplots te illustreren, het arceren van de grafiek.

Shaded Density Plots

Het invullen van de dichtheidsplot kan ons helpen om onderscheid te maken tussen overlappende verdelingen. Hoewel dit niet altijd een goede aanpak is, kan het helpen om het verschil tussen verdelingen te benadrukken. Om de dichtheidsplots te arceren, geven we shade = True door aan het kde_kws-argument in de distplot-aanroep.

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

Shaded Density Plot

Het al dan niet schaduw geven aan de plot is, net als andere planningsopties, een vraag die afhangt van het probleem! Voor deze grafiek lijkt het me zinvol omdat de arcering ons helpt de plots te onderscheiden in de gebieden waar ze elkaar overlappen. Nu hebben we eindelijk wat bruikbare informatie: Alaska Airlines vluchten zijn vaker vroeger dan United Airlines. De volgende keer dat u de keuze heeft, weet u welke luchtvaartmaatschappij u moet kiezen!

Rug Plots

Als u elke waarde in een verdeling wilt laten zien en niet alleen de afgevlakte dichtheid, kunt u een rugplot toevoegen. Dit toont elk gegevenspunt op de x-as, zodat we alle werkelijke waarden kunnen visualiseren. Het voordeel van het gebruik van seaborn’s distplot is dat we de rugplot kunnen toevoegen met een enkele parameteraanroep van rug = True (met ook wat opmaak).

Density Plot with Rug Plot for Alaska Airlines

Met veel datapunten kan de rugplot overvol worden, maar voor sommige datasets kan het nuttig zijn om elk datapunt te bekijken. De tapijtplot laat ons ook zien hoe de dichtheidsplot gegevens “creëert” waar er geen zijn, omdat hij in elk gegevenspunt een kernelverdeling maakt. Deze verdelingen kunnen lekken over het bereik van de oorspronkelijke gegevens en de indruk wekken dat Alaska Airlines vertragingen heeft die zowel korter als langer zijn dan werkelijk is geregistreerd. We moeten voorzichtig zijn met dit artefact van dichtheidsplots en kijkers erop wijzen!

Conclusies

Deze post heeft u hopelijk een reeks opties gegeven voor het visualiseren van een enkele variabele uit een of meerdere categorieën. Er zijn nog meer univariate (enkele variabele) plots die we kunnen maken zoals empirische cumulatieve dichtheidplots en quantiel-quantiel plots, maar voor nu laten we het bij histogrammen en dichtheidplots (en rugplots ook!). Maak je geen zorgen als de opties overweldigend lijken: met wat oefening zal het maken van een goede keuze gemakkelijker worden, en je kunt altijd om hulp vragen als dat nodig is. Bovendien is er vaak geen optimale keuze en zal de “juiste” beslissing afhangen van de voorkeur en de doelstellingen van de visualisatie. Het goede is, dat wat voor plot je ook wilt maken, er zal een manier zijn om het in Python te doen! Visualisaties zijn een effectief middel om resultaten te communiceren, en het kennen van alle beschikbare opties stelt ons in staat om de juiste figuur voor onze data te kiezen.

Ik verwelkom feedback en opbouwende kritiek en kan worden bereikt op Twitter @koehrsen_will.

admin

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.

lg