-
-
Save bjulius/e4ab68e67c982e6c00dfe3e7e216d9ae to your computer and use it in GitHub Desktop.
# Load necessary libraries | |
library(ggplot2) | |
library(dplyr) | |
library(tidyr) | |
library(gridExtra) | |
library(grid) | |
# Create the dataframe with the data from the image | |
sales_data <- data.frame( | |
Country = c("Finland", "Finland", "France", "France", "Netherlands", "Netherlands", | |
"Norway", "Norway", "Poland", "Poland"), | |
Year = c(2023, 2024, 2023, 2024, 2023, 2024, 2023, 2024, 2023, 2024), | |
TotalSales = c(160994, 186026, 360184, 652563, 818001, 400207, | |
272589, 157921, 943896, 1186120) | |
) | |
# Calculate changes from 2023 to 2024 | |
sales_summary <- sales_data %>% | |
pivot_wider(names_from = Year, values_from = TotalSales) %>% | |
mutate( | |
Change_K = (`2024` - `2023`) / 1000, # Convert to $K | |
Change_Percent = (`2024` - `2023`) / `2023` * 100 | |
) | |
# Set breaks for x-axes | |
k_breaks <- seq(-400, 300, 100) | |
pct_breaks <- seq(-40, 80, 20) | |
# Create plot for Change in $K | |
p1 <- ggplot(sales_summary) + | |
geom_segment( | |
aes(x = 0, y = Country, xend = Change_K, yend = Country, color = Change_K >= 0), | |
arrow = arrow(length = unit(0.3, "cm"), type = "closed"), | |
size = 1 | |
) + | |
geom_point(aes(x = 0, y = Country), color = "darkgrey", size = 3) + | |
scale_color_manual(values = c("FALSE" = "#F44336", "TRUE" = "#4CAF50")) + | |
scale_x_continuous( | |
breaks = k_breaks, | |
labels = function(x) paste0("$", x) | |
) + | |
labs(title = "Change in $K", x = NULL, y = NULL) + | |
theme_minimal() + | |
theme( | |
plot.title = element_text(hjust = 0.5, size = 12), | |
legend.position = "none", | |
panel.grid.minor = element_blank(), | |
panel.grid.major.y = element_blank(), | |
axis.text.y = element_text(size = 10) | |
) | |
# Create plot for Change in % | |
p2 <- ggplot(sales_summary) + | |
geom_segment( | |
aes(x = 0, y = Country, xend = Change_Percent, yend = Country, color = Change_Percent >= 0), | |
arrow = arrow(length = unit(0.3, "cm"), type = "closed"), | |
size = 1 | |
) + | |
geom_point(aes(x = 0, y = Country), color = "darkgrey", size = 3) + | |
scale_color_manual(values = c("FALSE" = "#F44336", "TRUE" = "#4CAF50")) + | |
scale_x_continuous( | |
breaks = pct_breaks, | |
labels = function(x) paste0(x, "%") | |
) + | |
labs(title = "Change in %", x = NULL, y = NULL) + | |
theme_minimal() + | |
theme( | |
plot.title = element_text(hjust = 0.5, size = 12), | |
legend.position = "none", | |
panel.grid.minor = element_blank(), | |
panel.grid.major.y = element_blank(), | |
axis.text.y = element_blank() # Remove y-axis text for the second plot | |
) | |
# Combine the plots with a shared title | |
grid.arrange( | |
p1, p2, | |
ncol = 2, | |
widths = c(1, 1), | |
top = textGrob( | |
"Change in Sales by Country from 2023 to 2024", | |
gp = gpar(fontsize = 16, fontface = "bold") | |
) | |
) |
Nick had some suggested edits. Here is the revised code:
Load necessary libraries
library(ggplot2)
library(dplyr)
library(tidyr)
library(gridExtra)
library(grid)
Create the dataframe with the data
sales_data <- data.frame(
Country = c("Finland", "Finland", "France", "France", "Netherlands", "Netherlands",
"Norway", "Norway", "Poland", "Poland"),
Year = c(2023, 2024, 2023, 2024, 2023, 2024, 2023, 2024, 2023, 2024),
TotalSales = c(160994, 186026, 360184, 652563, 818001, 400207, 272589, 157921,
943896, 1208230)
)
Calculate changes and sort countries by 2023 sales in descending order
sales_summary <- sales_data %>%
pivot_wider(names_from = Year, values_from = TotalSales) %>%
mutate(
Change_K = (2024
- 2023
) / 1000, # Convert to $K
Change_Percent = (2024
- 2023
) / 2023
* 100
) %>%
arrange(desc(2023
)) # Sort by 2023 sales in descending order
Create an explicit vector of countries in descending order of 2023 sales
ordered_countries <- sales_summary$Country
Set the factor levels explicitly to ensure correct ordering
sales_summary$Country <- factor(sales_summary$Country, levels = ordered_countries)
Set breaks for x-axes with adjusted ranges
k_breaks <- seq(-600, 600, 100)
pct_breaks <- seq(-60, 100, 20)
Create plot for nominal values (but keep "Change in $K" title)
p1 <- ggplot(sales_summary) +
geom_segment(
aes(x = 2023
, y = Country, xend = 2024
, yend = Country,
color = 2024
>= 2023
),
arrow = arrow(length = unit(0.12, "cm"), type = "open"),
size = 0.8
) +
geom_point(aes(x = 2023
, y = Country, color = 2024
>= 2023
), size = 2) +
scale_color_manual(values = c("FALSE" = "#F44336", "TRUE" = "#4CAF50")) +
scale_x_continuous(
breaks = seq(0, 1300000, 200000),
labels = function(x) paste0("$", x/1000, "K"),
limits = c(0, 1300000) # Ensure no values extend off chart
) +
scale_y_discrete(limits = rev(ordered_countries)) +
labs(title = "Change in $K", x = NULL, y = NULL) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, size = 12),
legend.position = "none",
panel.grid.minor = element_blank(),
panel.grid.major.y = element_blank(),
axis.text.y = element_text(size = 10),
axis.text.x = element_text(size = 6) # Even smaller x-axis labels
)
Create plot for Change in %
p2 <- ggplot(sales_summary) +
geom_segment(
aes(x = 0, y = Country, xend = Change_Percent, yend = Country,
color = Change_Percent >= 0),
arrow = arrow(length = unit(0.12, "cm"), type = "open"),
size = 0.8
) +
geom_point(aes(x = 0, y = Country, color = Change_Percent >= 0), size = 2) +
scale_color_manual(values = c("FALSE" = "#F44336", "TRUE" = "#4CAF50")) +
scale_x_continuous(
breaks = pct_breaks,
labels = function(x) paste0(x, "%"),
limits = c(-60, 100) # Extended axis from -60% to 100%
) +
scale_y_discrete(limits = rev(ordered_countries)) +
labs(title = "Change in %", x = NULL, y = NULL) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, size = 12),
legend.position = "none",
panel.grid.minor = element_blank(),
panel.grid.major.y = element_blank(),
axis.text.y = element_blank(),
axis.text.x = element_text(size = 6) # Even smaller x-axis labels
)
Combine the plots with a shared title
Extended width by 30% by adjusting the relative widths
grid.arrange(
p1, p2,
ncol = 2,
widths = c(1.3, 1.3), # Increased widths by 30%
top = textGrob(
"Change in Sales by Country from 2023 to 2024",
gp = gpar(fontsize = 16, fontface = "bold")
)
)
This is the code I generated by " vibe coding" in Claude Sonnet 3.7 extended.
Here's the prompt I used:
For the attached dataset, write the R code using ggplot2 to produce an arrow chart showing the changes in absolute and percentage sales by country from 2023 to 2024.
Style the chart as closely as possible to the attached screenshot - use the same fonts, colors, spacing, title podsition and style, axes (but substitute country for region), and have both charts share the same y-axis labels.
And this is the resulting chart:
