-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
3,680 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"livePreview.serverRoot": "_site" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
--- | ||
title: "Airline Revenues from Tickets vs Fees" | ||
postType: "random" | ||
description: "A breakdown of dis-aggregated airline revenues to see how much they make in fares vs fees." | ||
date: Oct 22, 2023 | ||
stylesheets: ["/css/blogPost.css"] | ||
--- | ||
|
||
## Introduction | ||
|
||
We all know the budget airlines (e.g. Frontier, Spirit) love to charge exhorbitant fees for everything from carry-on bags to seat selection. But how much of their overall revenue comes from these fees? And how does that compare to the legacy airlines (e.g. American, Delta, United)? In this post, we'll take a look at the breakdown of airline revenues to see how much they make of fares vs fees. | ||
|
||
## Data Sources | ||
Data is readily available in SEC 10-Q Filings (quarterly reports) under the category "Revenue Recognition". | ||
For example, | ||
* [Frontier Airlines 2023Q2, pg. 10](https://ir.flyfrontier.com/static-files/7fdeb254-16c5-44a4-bde9-392fd3558803) | ||
* [Delta Airlines 2023Q3, "Notes to Financial Statement" > "Revenue Recognition"](https://d18rn0p25nwr6d.cloudfront.net/CIK-0000027904/453e0eb5-f032-419a-9eab-ade5628da579.html#) | ||
|
||
I only did this for 2 airlines, but it's easy to obtain these for any airline. | ||
|
||
## Results (Pie Charts) | ||
[![Frontier Airlines Revenues by Category](images/FrontierAirlinesRevenues.svg){: style="width: 50%; float: left; margin: 0;" }](images/FrontierAirlinesRevenues.svg) | ||
[![Delta Airlines Revenues by Category](images/DeltaAirlinesRevenues.svg){: style="width: 50%; float: right; margin: 0;" }](images/DeltaAirlinesRevenues.svg) | ||
|
||
<div style="clear: both;"></div> | ||
|
||
Note that, for Frontier, "Service Fees" is often listed as something like "Carrier Interface Charge *Non-Refundable" on your ticket receipt, next to things like TSA fees and taxes, so it's basically just the the same as "Fare" from a consumer point of view, bringing the combined **"ticket price" percentage up to around 62%**. | ||
|
||
I would have liked to create a stacked bar chart with all the airlines, but I think it might be tricky to come up with a standardized set of categories to use, given how different Delta and Frontier are here. | ||
|
||
## Discussion | ||
Immediately obvious is that a significant portion of Frontier's revenue comes from "scamming" people out of baggage and seat selection prices. Or, alternatively, people who pay for bags and seats are subsidizing the fares of those who don't, which is in some senses more "fair" - if I fly without baggage then shouldn't I get to pay a lower fare? | ||
|
||
Meanwhile, Delta's revenue from Fares is a slightly larger proportion at 76% (compared to 62% for Frontier's Ticket Revenues). Also, rather than making money from baggage and seat selection (3.2% combined vs 33% for Frontier), Delta makes significant money from Loyalty programs and other random stuff (like maintenance services to other airlines and jet fuel refining). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import matplotlib.pyplot as plt" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# Frontier" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import matplotlib.colors as mcolors\n", | ||
"mcolors.CSS4_COLORS" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# Data for 6-months 2023\n", | ||
"labels = [\"Fare\", \"Service fees\", \"Baggage\", \"Seat selection\", \"Other passenger revenues\", \"Other revenues, e.g. cargo\"]\n", | ||
"values = [664, 462, 453, 146, 50, 40]\n", | ||
"adjusted_labels = [f\"{label}\\n(${value}M)\" for label, value in zip(labels, values)]\n", | ||
"custom_colors = [\"#A1DAE8\", \"#91cAd8\", \"#00aFFF\", \"#00BFFF\", \"#10cFFF\", \"peachpuff\"]\n", | ||
"\n", | ||
"fig, ax = plt.subplots(figsize=(12, 9))\n", | ||
"wedges, texts, autotexts = ax.pie(values, labels=adjusted_labels, autopct='%1.1f%%', startangle=180, counterclock=False, \n", | ||
" colors=custom_colors, pctdistance=0.85, textprops={'fontsize': 14})\n", | ||
"\n", | ||
"# Adjust font size and weight\n", | ||
"for text, autotext in zip(texts, autotexts):\n", | ||
" text.set(fontsize=14)\n", | ||
" autotext.set(fontsize=14, weight=\"bold\")\n", | ||
"\n", | ||
"# Add source text to the far bottom-right corner\n", | ||
"plt.figtext(0.97, 0.01, \"[source: Frontier Airlines 2023Q2 10-Q Filing]\", ha=\"right\", fontsize=10)\n", | ||
"\n", | ||
"ax.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.\n", | ||
"plt.title(\"Frontier Airlines Revenues\\n(for 6-months Ended June 30, 2023)\", fontsize=18)\n", | ||
"plt.tight_layout() # Adjust layout to prevent overlaps\n", | ||
"# plt.show()\n", | ||
"\n", | ||
"plt.savefig(\"_blog/images/FrontierAirlinesRevenues.svg\", format=\"svg\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# Delta" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import matplotlib.pyplot as plt\n", | ||
"\n", | ||
"# Data and labels\n", | ||
"labels_reordered = [\"Refinery\", \"Loyalty program\", \"Ancillary businesses\", \"Miscellaneous\", \"Fare\", \"Loyalty travel awards\", \"Travel-related services\"]\n", | ||
"values_reordered = [2817, 2291, 657, 790, 32801, 2547, 1387]\n", | ||
"adjusted_labels_reordered = [f\"{label} ${value}M\" if label != \"Fare\" else f\"{label}\\n${value}M\" for label, value in zip(labels_reordered, values_reordered)]\n", | ||
"colors_reordered = ['lightsalmon', 'darkorange', 'coral', 'peachpuff', 'lightblue', 'royalblue', 'deepskyblue']\n", | ||
"explode_values_final = [0, 0, 0, 0, 0, 0, 0]\n", | ||
"\n", | ||
"# Generating the pie chart\n", | ||
"fig, ax = plt.subplots(figsize=(12, 9))\n", | ||
"wedges, texts, autotexts = ax.pie(values_reordered, labels=adjusted_labels_reordered, autopct='%1.1f%%', startangle=180, counterclock=False, \n", | ||
" colors=colors_reordered, pctdistance=0.85, textprops={'fontsize': 14}, explode=explode_values_final)\n", | ||
"\n", | ||
"# Adjust font size and weight\n", | ||
"for text, autotext in zip(texts, autotexts):\n", | ||
" text.set(fontsize=14)\n", | ||
" autotext.set(fontsize=16, weight=\"bold\")\n", | ||
"\n", | ||
"# Positioning text boxes\n", | ||
"y_position = -1.5\n", | ||
"ax.text(-1.9, y_position, \"Passenger Revenues are shades of blue\\nNon-passenger revenues are shades of orange\", fontsize=12, ha=\"left\", va=\"bottom\")\n", | ||
"ax.text(1.5, y_position, \"[source: Delta Airlines 2023Q3 10-Q Filing]\", fontsize=12, ha=\"right\", va=\"bottom\")\n", | ||
"\n", | ||
"ax.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.\n", | ||
"plt.title(\"Delta Airlines Revenues\\n(for 9-months Ended September 30, 2023)\", fontsize=20)\n", | ||
"plt.tight_layout() # Adjust layout to prevent overlaps\n", | ||
"# plt.show()\n", | ||
"plt.savefig(\"_blog/images/DeltaAirlinesRevenues.svg\", format=\"svg\")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "base", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.9.15" | ||
}, | ||
"orig_nbformat": 4 | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
Oops, something went wrong.