I created the plot below, but I'm not sure how to adjust the figures to ensure they are positioned inside the plot area. Additionally, I would like to display the percentage savings, calculated as the difference between the "blue" (2024) and "red" (2023) values, prominently in the middle with larger font sizes.
Code:
energy_data_pyramid <- energy_data %>%
select(Year, Location, Month, energy_use_kWh) %>%
spread(key = Year, value = energy_use_kWh) %>%
mutate(
energy_use_kWh_2023 = ifelse(!is.na(`2023`), -`2023`, 0), # Negative for 2023
energy_use_kWh_2024 = ifelse(!is.na(`2024`), `2024`, 0) # Positive for 2024
) %>%
gather(key = "Year", value = "energy_use_kWh", energy_use_kWh_2023, energy_use_kWh_2024) %>%
mutate(
Year = recode(Year, "energy_use_kWh_2023" = "2023", "energy_use_kWh_2024" = "2024"),
Month = factor(Month, levels = c("January", "February", "March", "April", "May"))
)
# Check the transformed data
print(head(energy_data_pyramid))
# Create the pyramid plot
ggplot(energy_data_pyramid, aes(x = Month, y = energy_use_kWh, fill = Year)) +
geom_bar(stat = "identity", position = "stack") +
coord_flip() + # Flip coordinates to create the pyramid effect
scale_y_continuous(labels = abs) + # Ensure the y-axis labels are positive
geom_text(aes(label = round(abs(energy_use_kWh), 2)))+
facet_wrap(~Location, scales = "free_y") +
labs(title = "Bar sockets energy consumption: 2023 vs 2024",
x = "Month",
y = "Energy Use (kWh)",
fill = "Year") +
theme_minimal() +
theme(axis.text.y = element_text(size = 10),
axis.text.x = element_text(size = 10))
Data:
energy_data <- structure(list(Location = c("DG2-100-0-048", "DG2-100-0-048",
"DG2-100-0-048", "DG2-100-0-048", "DG2-100-0-048", "DG2-100-0-133",
"DG2-100-0-133", "DG2-100-0-133", "DG2-100-0-133", "DG2-100-0-133",
"DG2-100-0-210", "DG2-100-0-210", "DG2-100-0-210", "DG2-100-0-210",
"DG2-100-0-210", "DG2-100-0-048", "DG2-100-0-048", "DG2-100-0-048",
"DG2-100-0-048", "DG2-100-0-048"), Month = structure(c(4L, 2L, 1L,
3L, 5L, 4L, 2L, 1L, 3L, 5L, 4L, 2L, 1L, 3L, 5L, 4L, 2L, 1L, 3L, 5L),
levels = c("January", "February", "March", "April", "May"), class =
"factor"), `2023` = c(12.79, 11.81, 13.31, 13.15,
11.82, 11.99, 10.61, 12.28, 12.3, 11.43, 3.31, 3.1, 3.41, 3.54,
3.38, 12.79, 11.81, 13.31, 13.15, 11.82), `2024` = c(9.56, 9.06,
9.62, 9.77, 9.78, 8.93, 8.62, 9.01, 9.24, 9.08, 1.81, 2.24, 2.52,
2.67, 2.34, 9.56, 9.06, 9.62, 9.77, 9.78), Year = c("2023", "2023", "2023", "2023", "2023", "2023", "2023", "2023", "2023", "2023",
"2023", "2023", "2023", "2023", "2023", "2024", "2024", "2024",
"2024", "2024"), energy_use_kWh = c(-12.79, -11.81, -13.31, -13.15,
-11.82, -11.99, -10.61, -12.28, -12.3, -11.43, -3.31, -3.1, -3.41,
-3.54, -3.38, 9.56, 9.06, 9.62, 9.77, 9.78)), row.names = c(NA,
-20L), class = c("tbl_df", "tbl", "data.frame"))
You can conditionally set the alignment of the labels based on the Year
using an ifelse
. In the code below I additionally use a second ifelse
to put the labels outside of the bars for smaller values, but you can drop that line if it is not needed. To add the difference use a second geom_text
.
Note: I pre-processed your example data to get a proper wide and long dataset.
library(tidyverse)
energy_data_wide <- energy_data_pyramid |>
select(-energy_use_kWh, -Year) |>
distinct(Location, Month, .keep_all = TRUE)
energy_data_long <- energy_data_wide |>
pivot_longer(-c(Location, Month),
names_to = "Year",
values_to = "energy_use_kWh"
) |>
mutate(
energy_use_kWh = if_else(Year == 2023, -energy_use_kWh, energy_use_kWh),
hjust = ifelse(Year == 2023, 0, 1),
hjust = ifelse(abs(energy_use_kWh) < 5, 1 - hjust, hjust)
)
ggplot(energy_data_long, aes(x = energy_use_kWh, y = Month)) +
geom_col(aes(fill = Year)) +
scale_x_continuous(labels = abs) + # Ensure the y-axis labels are positive
geom_label(
aes(
hjust = hjust,
label = round(abs(energy_use_kWh), 2)
),
fill = NA, label.size = 0
) +
geom_text(
data = energy_data_wide,
aes(
x = 0,
label = round(`2024` - `2023`, 2),
),
fontface = "bold",
size = 14 / .pt
) +
facet_wrap(~Location, scales = "free_y") +
labs(
title = "Bar sockets energy consumption: 2023 vs 2024",
y = "Month",
x = "Energy Use (kWh)",
fill = "Year"
) +
theme_minimal() +
theme(
axis.text = element_text(size = 10)
)