This dataset is a listing of Airbnb rentals in London, England over the time period of 2011 through 2021. The data consists of 67,904 total rows of rentals; 65,779 of those being unique rentals. The information for each rental consists of the name of the rental, the host id, the host name, the neighborhood within London in which it is located, the latitude and longitude coordinates of the rental, the room type, the price per night, the minimum nights required to book, the number of reviews the rental has, the number of reviews the rental receives per month, the number of nights per year the rental is available and the number of reviews received in the last 12 months.
library(flexdashboard)
library(data.table)
library(ggplot2)
library(scales)
library(dplyr)
library(lubridate)
library(ggrepel)
london_listings = fread("C:\\Users\\lpatr\\OneDrive\\Documents\\Loyola\\DS736- Visualization\\airbnb_listings_london.csv")
First, I wanted to find out the types of rooms available for rent and then their distribution. There are four types of rentals: entire home/apartment, hotel room, private room, and shared room. The pie chart in visualization one shows this distribution, and as it shows, the entire home/apartment is the type of room most available.
Next, I thought it would be interesting to see which neighborhoods had the most Airbnb rentals, so in visualization 2 I show the top 10 neighborhoods. The neighborhood of Westminster came in as the most popular London neighborhood, with 7,230 total Airbnb rentals.
Curious to see which types of rentals were available in the neighborhoods, I made a couple of stacked bar charts in visualization 3. The top graph shows the distribution of rooms types within all the neighborhoods where there are rentals available. Breaking it down further for easier reading, the second chart shows just the distribution of room types within the top 10 neighborhoods. As expected, entire home/apartment dominates the room types.
Visualization 4 shows the number of reviews over time for the Airbnb rentals in this dataset. I thought that in by plotting the year of the review against the number of total reviews within that year I could potentially show trends such as seasonal or the growing popularity of Airbnb. As you can see in the line graph there are a couple definite trends, first being the rise in Airbnb popularity. What starts as something with a very small amount of reviews in the first year (7 total in 2011) becomes something with immense popularity with 13,383 total reviews in 2019. What else is clear is how Airbnb was affected by the 2020 COVID-19 pandemic. Reviews plummet in 2020 and then begin to rise again over the next year once travel became safer.
Lastly, I wanted to show the concentration of the Airbnb rentals in London. While we know what the most popular neighborhoods to rent in are in London, without knowing the city it’s hard to visualize where they are in respect to one another. Visualization 5 shows a heatmap of the latitude and longitude of each rental. As you can see by the dark blue spots on the map, the highest concentration of rentals is in the center of the city.
#create data frame of room types
types <- count(london_listings, room_type)
#find percentages by room type
total_n <- sum(types$n)
rooms_df <- types %>%
select(room_type, n) %>%
mutate(percent_of_total = round(100*n/total_n, 2)) %>%
data.frame()
#pie chart
ggplot(data = rooms_df, aes(x = "", y = n, fill = room_type)) +
geom_bar(stat = "identity", position = "fill") +
coord_polar(theta = "y", start = 0) +
labs(fill = "Room Type", x = NULL, y = NULL, title = "Room Types within London Airbnb Rentals") +
theme_light() +
theme(plot.title = element_text(hjust = 0.5, size = 20), axis.text = element_blank(),
axis.ticks = element_blank(), panel.grid = element_blank(),
legend.title = element_text(size = 20),
legend.text = element_text(size = 15)) +
scale_fill_brewer(palette = "Set2") +
geom_text(aes(x = 1.55, label = paste0(round(percent_of_total, 2), "%"), y = n/2), position = position_fill(vjust = 0.5), size = 5)
neighbourhoods <- count(london_listings, neighbourhood)
#create df of most popular neighbourhoods in decreasing order
neighborhoods <- neighbourhoods[order(neighbourhoods$n, decreasing = TRUE),]
#bar chart
ggplot(neighborhoods[1:10,], aes(x = reorder(neighbourhood, -n), y = n)) +
geom_bar(color = "black", fill = "darkgreen", stat = "identity") +
labs(title = "Top 10 AirBnB Neighbourhoods in London", x = "Neighbourhood", y = "Total Number of Rentals") +
theme(plot.title = element_text(hjust = 0.5, size = 20),
axis.title.x = element_text(size = 15),
axis.title.y = element_text(size = 15)) +
scale_x_discrete(labels = label_wrap(10)) +
scale_y_continuous(labels = comma) +
geom_text(aes(label = comma(n)), vjust = -0.4, color = "black")
#stacked bar chart for all of the neighbourhoods
ggplot(london_listings, aes(x = neighbourhood, fill = room_type)) +
geom_bar(position = "stack") +
labs(x = "Neighborhood", y = "Number of Listings", fill = "Room Type", title = "Distribution of Room Types by Neighborhood in London Airbnb Listings") +
theme_minimal() +
coord_flip() +
theme(plot.title = element_text(hjust = 0.5, size = 25),
legend.title = element_text(size = 20),
legend.text = element_text(size = 15),
axis.title.x = element_text(size = 20),
axis.title.y = element_text(size = 20),
axis.text.x = element_text(size = 15),
axis.text.y = element_text(size = 15))+
scale_y_continuous(labels = comma) +
geom_text(data = neighborhoods, aes(x = neighbourhood, y = n, label = comma(n), fill = NULL), hjust = -0.1, size = 4)
#create df for bar labels
list_neigh <- count(london_listings, neighbourhood)
list_neigh <- list_neigh[order(list_neigh$n, decreasing = TRUE),]
top_neighborhoods1 <- list_neigh[1:10]
filtered_listings <- london_listings %>%
filter(neighbourhood %in% top_neighborhoods1$neighbourhood) %>%
select(neighbourhood, room_type)
#stacked bar chart for just top 10 neighbourhoods
ggplot(filtered_listings, aes(x = neighbourhood, fill = room_type)) +
geom_bar(position = position_stack(reverse = TRUE)) +
labs(x = "Neighborhood", y = "Number of Listings", fill = "Room Type",
title = "Distribution of Room Types by Neighborhood in London Airbnb Listings (Top 10)") +
coord_flip() +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5, size = 25),
legend.title = element_text(size = 20),
legend.text = element_text(size = 15),
axis.title.x = element_text(size = 20),
axis.title.y = element_text(size = 20),
axis.text.x = element_text(size = 15),
axis.text.y = element_text(size = 15)) +
scale_y_continuous(labels = comma) +
geom_text(data = top_neighborhoods1, aes(x = neighbourhood, y = n, label = comma(n), fill = NULL), hjust = -0.1, size = 4)
#create df for reviews per year
reviews_df <- london_listings %>%
select(last_review) %>%
mutate(year = year(mdy(last_review))) %>%
group_by(year) %>%
summarise(n = length(last_review), .groups = "keep") %>%
data.frame()
#remove NAs
reviews_df <- reviews_df[!is.na(reviews_df$year),]
#create xaxis labels
x_axis_labels <- min(reviews_df$year): max(reviews_df$year)
#find high and low points
hi_lo <- reviews_df %>%
filter(n == min(n) | n == max(n)) %>%
data.frame()
#line plot
ggplot(reviews_df, aes(x = year, y = n)) +
geom_line(color = "navy", size = 2) +
geom_point(shape = 21, size = 4, color = "red", fill = "white") +
labs(title = "Total Number of Reviews of London Airbnbs by Year", x = "Year", y = "Total Number of Reviews") +
theme_light() +
theme(plot.title = element_text(hjust = 0.5, size = 20),
legend.title = element_text(size = 20),
legend.text = element_text(size = 15),
axis.title.x = element_text(size = 15),
axis.title.y = element_text(size = 15)) +
scale_y_continuous(labels = comma) +
scale_x_continuous(labels = x_axis_labels, breaks = x_axis_labels, minor_breaks = NULL) +
geom_point(data = hi_lo, aes(x = year, y = n), shape = 21, size = 4, fill = "red", color = "red") +
geom_label_repel(aes(label = ifelse(n == max(n) | n == min(n), scales::comma(n),"")),
box.padding = 1,
point.padding = 1,
size = 4, color = "gray40")
#aggregate the longitude and latitude
london_agg <- london_listings %>%
mutate(long_rounded = round(longitude, 2), lat_rounded = round(latitude, 2)) %>%
group_by(long_rounded, lat_rounded) %>%
summarise(count = n(), .groups = "keep") %>%
data.frame()
#add additional breaks in heatmap
breaks <- c(seq(0, max(london_agg$count), by = 100))
#heatmap
ggplot(london_agg, aes(x = long_rounded, y = lat_rounded, fill = count)) +
geom_tile(color = "black") +
geom_text(aes(label = comma(count))) +
labs(title = "Heatmap: Concentration of Airbnb Rentals in London", x = "Longitude", y = "Latitude", fill = "Number of Rentals", size = 15) +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5, size = 40),
axis.title.x = element_text(size = 32),
axis.title.y = element_text(size = 32),
axis.text.x = element_text(size = 20),
axis.text.y = element_text(size = 20),
legend.title = element_text(size = 20),
legend.text = element_text(size = 15)) +
scale_fill_continuous(low = "lightcyan", high = "dodgerblue4", breaks = breaks) +
guides(fill = guide_legend(override.aes = list(color = "black")))
In conclusion of this exploration of the London Airbnb rental listings dataset, we have uncovered trends and distributions that highlight the short-term rental market in London. Firstly, through finding travelers’ preference for entire homes/apartments, we can infer an importance of privacy and space among travelers. Through an exploration of the most popular neighbohoods in London as well as the heatmap visualization of the rentals, we can see how Westminster is highlighted, showing the area’s appeal to visitors seeking to experience the heart of London. The heatmap allows a clear view of where travelers most like to stay within the city. The review trends over time provided a narrative of Airbnb’s growing popularity in London, only to be interrupted by the global pandemic in 2020. This interruption offered a great illustration of external factors’ impact on travel behavior and the resilience of the platform as it began to recover in the following year. As the short term rental market continues to evolve, the insights gleaned from datasets such as this can inform both travelers and hosts, as well as policymakers and stakeholders interested in the dynamics of tourism and accommodation.