Load Necessary Libraries

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

Filter for Selected Minerals

# List of selected minerals
selected_minerals <- c(
  "Aluminum", "Antimony", "Arsenic", "Barite", "Beryllium", "Bismuth", "Cerium", "Cesium", 
  "Chromium", "Cobalt", "Dysprosium", "Erbium", "Europium", "Fluorspar", "Gadolinium", 
  "Gallium", "Germanium", "Graphite", "Hafnium", "Holmium", "Indium", "Iridium", "Lanthanum", 
  "Lithium", "Lutetium", "Magnesium", "Manganese", "Neodymium", "Nickel", "Niobium", 
  "Palladium", "Platinum", "Praseodymium", "Rhodium", "Rubidium", "Ruthenium", "Samarium", 
  "Scandium", "Tantalum", "Tellurium", "Terbium", "Thulium", "Tin", "Titanium", "Tungsten", 
  "Vanadium", "Ytterbium", "Yttrium", "Zinc", "Zirconium"
)

# Load datasets (update paths as needed)
reliance_data <- read.csv("https://raw.githubusercontent.com/hawa1983/DATA-608/refs/heads/main/Story%207/MCS2024_Fig2_Net_Import_Reliance.csv")

source_data <- read.csv("https://raw.githubusercontent.com/hawa1983/DATA-608/refs/heads/main/Story%207/MCS2024_Fig3_Major_Import_Sources.csv") 

end_use_data <- read.csv("https://raw.githubusercontent.com/hawa1983/DATA-608/refs/heads/main/Story%207/MCS2024_T4_Critical_Minerals_End_Use.csv") 

domestic_production_gap <- read.csv("https://raw.githubusercontent.com/hawa1983/DATA-608/refs/heads/main/Story%207/MCS2024_T5_Critical_Minerals_Salient.csv")

Illustrating strategic use of criticl menerals

# Load necessary libraries
library(ggplot2)
library(dplyr)

# Define data: Critical minerals and their strategic uses
minerals_data <- data.frame(
  Mineral = c(
    "Aluminum", "Antimony", "Arsenic", "Barite", "Beryllium", "Bismuth", "Cerium",
    "Cesium", "Chromium", "Cobalt", "Dysprosium", "Erbium", "Europium", "Fluorspar",
    "Gadolinium", "Gallium", "Germanium", "Graphite", "Hafnium", "Holmium", "Indium",
    "Iridium", "Lanthanum", "Lithium", "Lutetium", "Magnesium", "Manganese", 
    "Neodymium", "Nickel", "Niobium", "Palladium", "Platinum", "Praseodymium", 
    "Rhodium", "Rubidium", "Ruthenium", "Samarium", "Scandium", "Tantalum", 
    "Tellurium", "Terbium", "Thulium", "Tin", "Titanium", "Tungsten", "Vanadium", 
    "Ytterbium", "Yttrium", "Zinc", "Zirconium"
  ),
  Use_Category = c(
    "Economy", "Defense", "Technology", "Energy", "Defense", "Technology", 
    "Technology", "Research", "Economy", "Technology", "Technology", "Technology", 
    "Technology", "Economy", "Technology", "Technology", "Technology", 
    "Energy", "Defense", "Technology", "Technology", "Energy", "Energy", 
    "Technology", "Technology", "Economy", "Economy", "Technology", "Economy", 
    "Defense", "Economy", "Economy", "Technology", "Energy", "Technology", 
    "Technology", "Defense", "Technology", "Technology", "Energy", "Technology", 
    "Energy", "Economy", "Economy", "Economy", "Technology", "Technology", 
    "Economy", "Technology", "Technology"
  ),
  Importance = c(
    80, 50, 30, 40, 60, 30, 45, 20, 70, 65, 55, 50, 45, 60, 
    50, 55, 40, 60, 35, 40, 50, 30, 60, 80, 25, 70, 70, 50, 
    60, 45, 55, 60, 50, 30, 35, 40, 50, 45, 60, 35, 50, 45, 
    60, 70, 50, 45, 55, 65, 60, 70
  )
)

# Add jitter to separate overlapping points
ggplot(minerals_data, aes(x = Use_Category, y = Importance, color = Use_Category)) +
  geom_point(position = position_jitter(width = 0.4, height = 5), alpha = 0.7, size = 3) +  # Add jitter to y-axis
  geom_text(aes(label = Mineral), position = position_jitter(width = 0.2, height = 2), 
            vjust = 0, hjust = 1.5, size = 2, color = "black") +  # Jitter text for better readability
  labs(
    title = "Strategic Uses of Critical Minerals",
    x = "Use Category",
    y = "Relative Importance",
    color = "Use Category"
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(size = 10, angle = 45, hjust = 1),
    axis.text.y = element_text(size = 10),
    plot.title = element_text(size = 14, face = "bold")
  )

Applications of Critical Minerals

This plot highlights the primary applications of critical minerals.

# Load the data (update the file path as needed)
end_use_data <- read.csv("https://raw.githubusercontent.com/hawa1983/DATA-608/refs/heads/main/Story%207/MCS2024_T4_Critical_Minerals_End_Use.csv")

# Count the primary applications and create a bar chart
end_use_data %>%
  count(Primary.Applications, sort = TRUE) %>%
  head(10) %>%
  ggplot(aes(x = reorder(Primary.Applications, -n), y = n)) +
  geom_bar(stat = "identity", fill = "#117733") +
  coord_flip() +
  labs(
    title = "Primary Applications of Critical Minerals",
    x = "Applications",
    y = "Frequency"
  ) +
  theme_minimal() +
  theme_minimal() +
  theme(
   panel.grid.major = element_line(color = "gray100", size = 0.25),  # Fade out major gridlines
   panel.grid.minor = element_blank()  # Remove minor gridlines
  )
## Warning: The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0.
## ℹ Please use the `linewidth` argument instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Major Source Countries for Critical Minerals

This plot shows the number of critical minerals supplied by each country.

library(dplyr)
library(ggplot2)

# Load the CSV file
commodity_count_data <- read.csv("https://raw.githubusercontent.com/hawa1983/DATA-608/refs/heads/main/Story%207/MCS2024_Fig3_Major_Import_Sources.csv")

colnames(commodity_count_data) <- c("Country", "Commodity_Count", "Map_Class")

# Inspect the data to ensure it is loaded correctly
head(commodity_count_data)
##     Country Commodity_Count Map_Class
## 1 Australia               6    4 to 6
## 2   Austria               2    1 to 3
## 3   Belarus               1    1 to 3
## 4   Belgium               8   7 to 12
## 5   Bolivia               3    1 to 3
## 6    Brazil              10   7 to 12
# Define updated classifications for countries (including Switzerland and Philippines as Allies)
country_classification <- list(
  "Australia" = "Ally", "Canada" = "Ally", "United States" = "Ally", "Germany" = "Ally",
  "France" = "Ally", "Japan" = "Ally", "Belgium" = "Ally", "United Kingdom" = "Ally",
  "Austria" = "Ally", "South Korea" = "Ally", "Israel" = "Ally", "Norway" = "Ally",
  "Switzerland" = "Ally", "Philippines" = "Ally", # Added Switzerland and Philippines as Allies
  "China" = "Competitor", "Russia" = "Competitor", "Belarus" = "Competitor",
  "India" = "Neutral", "Mexico" = "Neutral", "Brazil" = "Neutral", "South Africa" = "Neutral",
  "Kazakhstan" = "Neutral", "Morocco" = "Neutral", "Malaysia" = "Neutral", "Vietnam" = "Neutral",
  "Peru" = "Neutral", "Jamaica" = "Neutral", "Indonesia" = "Neutral", "Bolivia" = "Neutral",
  "Ukraine" = "Ally", "Taiwan" = "Ally", "Poland" = "Ally", "Netherlands" = "Ally",
  "Finland" = "Ally", "Italy" = "Ally", "Ireland" = "Ally", "Unknown" = "Unknown"
)

# Add classification column to the data
commodity_count_data <- commodity_count_data %>%
  mutate(
    Classification = country_classification[Country] %||% "Unknown",
    Classification = factor(Classification, levels = c("Ally", "Competitor", "Neutral", "Unknown")) # Convert to factor
  )

# Plot the data
ggplot(commodity_count_data, aes(x = reorder(Country, -Commodity_Count), y = Commodity_Count, fill = Classification)) +
  geom_bar(stat = "identity") +
  coord_flip() +
  scale_fill_manual(
    values = c("Ally" = "#117733", "Competitor" = "#CC6677", "Neutral" = "#88CCEE", "Unknown" = "gray"),
    labels = c("Ally", "Competitor", "Neutral", "Unknown")
  ) +
  labs(
    title = "Major Source Countries for Critical Minerals (Classification)",
    x = "Country",
    y = "Number of Critical Minerals Supplied",
    fill = "Country Classification"
  ) +
  theme_minimal() +
  theme(
   panel.grid.major = element_line(color = "gray99", size = 0.25),  # Fade out major gridlines
   panel.grid.minor = element_blank()  # Remove minor gridlines
  )

Range of Strategic Minerals by Allies, Competitors, and Neutral Countries

library(dplyr)
library(ggplot2)

# Load the CSV file
commodity_count_data <- read.csv("https://raw.githubusercontent.com/hawa1983/DATA-608/refs/heads/main/Story%207/MCS2024_Fig3_Major_Import_Sources.csv")

colnames(commodity_count_data) <- c("Country", "Commodity_Count", "Map_Class")

# Define updated classifications for countries
country_classification <- list(
  "Australia" = "Ally", "Canada" = "Ally", "United States" = "Ally", "Germany" = "Ally",
  "France" = "Ally", "Japan" = "Ally", "Belgium" = "Ally", "United Kingdom" = "Ally",
  "Austria" = "Ally", "South Korea" = "Ally", "Israel" = "Ally", "Norway" = "Ally",
  "Switzerland" = "Ally", "Philippines" = "Ally",
  "China" = "Competitor", "Russia" = "Competitor", "Belarus" = "Competitor",
  "India" = "Neutral", "Mexico" = "Neutral", "Brazil" = "Neutral", "South Africa" = "Neutral",
  "Kazakhstan" = "Neutral", "Morocco" = "Neutral", "Malaysia" = "Neutral", "Vietnam" = "Neutral",
  "Peru" = "Neutral", "Jamaica" = "Neutral", "Indonesia" = "Neutral", "Bolivia" = "Neutral",
  "Ukraine" = "Ally", "Taiwan" = "Ally", "Poland" = "Ally", "Netherlands" = "Ally",
  "Finland" = "Ally", "Italy" = "Ally", "Ireland" = "Ally", "Unknown" = "Unknown"
)

# Add classification column to the data
commodity_count_data <- commodity_count_data %>%
  mutate(
    Classification = country_classification[Country] %||% "Unknown",
    Classification = factor(Classification, levels = c("Ally", "Competitor", "Neutral", "Unknown")),
    Map_Class = factor(Map_Class, levels = c("1 to 3", "4 to 6", "7 to 12", "19 to 24")) # Order the Map_Class levels
  )

# Aggregate data by Classification and Map_Class
reliance_summary <- commodity_count_data %>%
  group_by(Classification, Map_Class) %>%
  summarize(Total_Commodities = sum(Commodity_Count), .groups = "drop")

# Stacked bar chart
ggplot(reliance_summary, aes(x = Classification, y = Total_Commodities, fill = Map_Class)) +
  geom_bar(stat = "identity", position = "stack", color = "black", size = 0.6, 
           aes(alpha = ifelse(Classification %in% c("Competitor", "Neutral"), 1, 0.3))) +
  scale_fill_manual(
    values = c("1 to 3" = "#F4A582", "4 to 6" = "#92C5DE", "7 to 12" = "#D5A6BD", "19 to 24" = "#66C2A5"),
    breaks = c("1 to 3", "4 to 6", "7 to 12", "19 to 24") # Ensure legend order matches
  ) +
  scale_alpha_identity() +
  labs(
    title = "Reliance on Allies, Competitors, and Neutral Countries",
    x = "Country Classification",
    y = "Total Number of Critical Minerals Supplied",
    fill = "Range of Minerals Supplied"
  ) +
  theme_minimal() +
  theme(
    legend.position = "right", # Position legend for better visibility
    panel.grid = element_blank() # Remove grid lines
  )
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Geographic illustration of suppliers by category

library(ggplot2)
library(purrr)
library(maps)
## 
## Attaching package: 'maps'
## The following object is masked from 'package:purrr':
## 
##     map
library(dplyr)

# World map data
world <- map_data("world")

# Add U.S. as an Importer to geo_data
geo_data <- commodity_count_data %>%
  bind_rows(data.frame(
    Country = "USA",  # Ensure naming aligns with the `world` data
    Commodity_Count = NA,  # U.S. is an importer, not a supplier
    Map_Class = NA,
    Classification = "Importer"
  )) %>%
  mutate(Classification = case_when(
    is.na(Classification) & !is.na(Commodity_Count) ~ "Other Supplier",
    TRUE ~ Classification
  ))

# Merge with world map data
world_map <- world %>%
  left_join(geo_data, by = c("region" = "Country")) %>%
  mutate(Classification = replace_na(Classification, "Not a Supplier"))

# Plot the map
ggplot(world_map, aes(x = long, y = lat, group = group, fill = Classification)) +
  geom_polygon(color = "white") +
  scale_fill_manual(
    values = c(
      "Importer" = "#F0C808",
      "Ally" = "#117733",
      "Competitor" = "#CC6677",
      "Neutral" = "#88CCEE",
      "Other Supplier" = "#9467BD",
      "Not a Supplier" = "lightgrey"
    )
  ) +
  labs(
    title = "Global Suppliers of Critical Minerals with U.S. as Importer",
    fill = "Country Classification"
  ) +
  theme_minimal() +
  theme(
    axis.text = element_blank(),        # Remove axis text
    axis.ticks = element_blank(),       # Remove axis ticks
    axis.title = element_blank(),       # Remove axis labels
    panel.grid = element_blank(),       # Remove grid lines
    legend.position = "bottom"          # Move legend to the bottom
  )

Visualization of Top Minerals with the Highest Shortfall by Leading Supplier

# 4. Strategic Gaps in Domestic Production
# Clean numeric data and calculate shortfall
domestic_production_gap <- domestic_production_gap %>%
  mutate(
    Primary_prod = as.numeric(gsub("[^0-9\\.]", "", Primary_prod)),
    Apparent_Consuption = as.numeric(gsub("[^0-9\\.]", "", Apparent_Consuption)),
    Shortfall = Apparent_Consuption - Primary_prod
  ) %>%
  filter(!is.na(Shortfall))

# Plot with highlighted and faded bars
domestic_production_gap %>%
  arrange(desc(Shortfall)) %>%
  head(10) %>%
  ggplot(aes(x = reorder(Critical_mineral, -Shortfall), y = Shortfall)) +
  geom_bar(
    stat = "identity", 
    aes(fill = ifelse(Critical_mineral %in% c("Zinc", "Manganese", "Chromium"), "Highlight", "Fade"))
  ) +
  scale_fill_manual(
    values = c("Highlight" = "#CC6677", "Fade" = "lightgrey"),  # Highlighted and faded colors
    guide = "none"  # Remove legend for fill
  ) +
  coord_flip() +
  labs(
    title = "Strategic Gaps in Domestic Production for Top Minerals",
    x = "Critical Mineral",
    y = "Shortfall (Metric Tons)"
  ) +
  theme_minimal() +
  theme(
    panel.grid = element_blank(),  # Remove grid lines
    axis.text.y = element_text(size = 10)  # Adjust axis label size
  )

glimpse(domestic_production_gap) 
## Rows: 20
## Columns: 14
## $ Source                       <chr> "MCS2024", "MCS2024", "MCS2024", "MCS2024…
## $ Year                         <chr> "2023_estimated", "2023_estimated", "2023…
## $ Critical_mineral             <chr> "Antimony", "Arsenic", "Beryllium", "Bism…
## $ Primary_prod                 <dbl> 0, 0, 190, 0, 0, 500, 0, 0, 0, 0, 17000, …
## $ Secondary_prod               <chr> "4000", NA, NA, "80", "100000", "2100", "…
## $ Apparent_Consuption          <dbl> 22000, 6400, 150, 1400, 380000, 6400, 19,…
## $ Net_Import_Reliance          <chr> "82", "100", NA, "94", "74", "67", "100",…
## $ Primary_import_source        <chr> "China", "China", "Kazakhstan", "China", …
## $ Leading_source_country       <chr> "China", "Peru", "United States", "China"…
## $ Leading_country_prod         <int> 40000, 27000, 190, 16000, 18000000, 17000…
## $ World_total_prod             <int> 83000, 60000, 330, 20000, 41000000, 23000…
## $ World_prod_notes             <chr> "", "Arsenic trioxide.", "", "", "", "", …
## $ Leading_source_precent_world <int> 48, 45, 58, 80, 44, 74, 98, 77, 66, 36, 5…
## $ Shortfall                    <dbl> 22000, 6400, -40, 1400, 380000, 5900, 19,…
# Load necessary libraries
library(dplyr)
library(ggplot2)
library(scales)  # For formatting the axis labels
## 
## Attaching package: 'scales'
## The following object is masked from 'package:purrr':
## 
##     discard
## The following object is masked from 'package:readr':
## 
##     col_factor
# Load the data (update the file path as needed)
domestic_production_gap <- read.csv("https://raw.githubusercontent.com/hawa1983/DATA-608/refs/heads/main/Story%207/MCS2024_T5_Critical_Minerals_Salient.csv")

# Clean the numeric data and calculate shortfall
domestic_production_gap <- domestic_production_gap %>%
  mutate(
    Primary_prod = as.numeric(gsub("[^0-9\\.]", "", Primary_prod)),
    Apparent_Consuption = as.numeric(gsub("[^0-9\\.]", "", Apparent_Consuption)),
    Shortfall = Apparent_Consuption - Primary_prod
  ) %>%
  filter(!is.na(Shortfall))

# Plot the top shortfalls
domestic_production_gap %>%
  arrange(desc(Shortfall)) %>%
  head(10) %>%
  ggplot(aes(x = reorder(Critical_mineral, -Shortfall), y = Shortfall)) +
  geom_bar(stat = "identity", fill = "#CC6677") +
  coord_flip() +
  labs(
    title = "Strategic Gaps in Domestic Production for Top Minerals",
    x = "Critical Mineral",
    y = "Shortfall (Metric Tons)"
  ) +
  scale_y_continuous(labels = label_comma()) +  # Format the y-axis with commas
  theme_minimal()

# Load necessary libraries
library(dplyr)
library(tidyr)

# Debug: Inspect the column names
print("Column names in reliance_data:")
## [1] "Column names in reliance_data:"
print(colnames(reliance_data))
## [1] "Source"                         "Import_Share_Order"            
## [3] "Commodity"                      "Net_Import_Reliance_pct_2023"  
## [5] "Major_Import_Sources_2019_2022" "Notes"
# Ensure correct column name
# Replace with the actual column name if different
correct_column_name <- "Major_Import_Sources_2019_2022" # Adjust this if necessary

# Check if the column exists in the dataset
if (!(correct_column_name %in% colnames(reliance_data))) {
  stop(paste("Column", correct_column_name, "does not exist in reliance_data."))
}

# Break up countries and assign reliance rank
reliance_data_expanded <- reliance_data %>%
  mutate(
    # Ensure the column is properly split into a list of countries
    Countries = strsplit(as.character(.data[[correct_column_name]]), ",\\s*")
  ) %>%
  unnest(Countries) %>%  # Expand the list into individual rows
  group_by(Commodity) %>%  # Group by the mineral/commodity
  mutate(
    reliance_rank = row_number()  # Rank the countries within each commodity group
  ) %>%
  ungroup()

# View the resulting dataset
glimpse(reliance_data_expanded)
## Rows: 228
## Columns: 8
## $ Source                         <chr> "MCS2024", "MCS2024", "MCS2024", "MCS20…
## $ Import_Share_Order             <int> 1, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, …
## $ Commodity                      <chr> "ARSENIC, all forms", "ARSENIC, all for…
## $ Net_Import_Reliance_pct_2023   <int> 100, 100, 100, 100, 100, 100, 100, 100,…
## $ Major_Import_Sources_2019_2022 <chr> "China, Morocco, Malaysia, Belgium", "C…
## $ Notes                          <chr> "Descending order of import share. Impo…
## $ Countries                      <chr> "China", "Morocco", "Malaysia", "Belgiu…
## $ reliance_rank                  <int> 1, 2, 3, 4, 1, 2, 1, 1, 2, 3, 4, 1, 2, …

Import Reliance Rack and Frequency of Countries in each Rank

# Load necessary libraries
library(dplyr)
library(ggplot2)

# Calculate the proportion of reliance ranks for each country
country_reliance_rank <- reliance_data_expanded %>%
  group_by(Countries, reliance_rank) %>%  # Group by country and reliance rank
  summarize(count = n(), .groups = "drop") %>%  # Count occurrences of each rank per country
  group_by(Countries) %>%
  mutate(proportion = count / sum(count)) %>%  # Calculate proportion of each rank per country
  ungroup()

# Ensure reliance_rank is treated as a factor
country_reliance_rank <- country_reliance_rank %>%
  mutate(reliance_rank = as.factor(reliance_rank))  # Convert reliance_rank to a factor

# Calculate the number of minerals each country is involved with
country_counts <- country_reliance_rank %>%
  group_by(Countries) %>%
  summarize(total_minerals = sum(count), .groups = "drop")  # Total count of minerals per country

# Reorder countries based on the total reliance count
country_order <- country_counts %>%
  arrange(desc(total_minerals)) %>%
  pull(Countries)  # Extract countries ordered by total minerals

# Update `country_reliance_rank` with reordered country levels
country_reliance_rank <- country_reliance_rank %>%
  mutate(Countries = factor(Countries, levels = country_order))

# Prepare data: Calculate the frequency of each country in each reliance rank
ranked_country_frequencies <- country_reliance_rank %>%
  group_by(reliance_rank, Countries) %>%
  summarize(frequency = sum(count), .groups = "drop")  # Count occurrences of each rank for each country

# Accessible color palette
accessible_colors <- c(
  "1" = "#117733",        # Dark green
  "4" = "#CC6677",        # Reddish
  "2" = "#88CCEE",        # Light blue
  "3" = "#999999"         # Gray
)

# Create bar charts, one for each rank
ggplot(ranked_country_frequencies, aes(x = reorder(Countries, -frequency), y = frequency, fill = reliance_rank)) +
  geom_bar(stat = "identity") +
  facet_wrap(~ reliance_rank, scales = "free_y") +  # Create a facet for each rank
  labs(
    title = "Frequency of Countries in Each Reliance Rank (Top Four Ranks)",
    x = "Country",
    y = "Frequency",
    fill = "Reliance Rank"
  ) +
  scale_fill_manual(values = accessible_colors) +  # Use the accessible color palette
  theme_minimal() +
  theme(
    axis.text.x = element_text(size = 5, angle = 90, hjust = 1, vjust = 1),  # Adjust alignment for better readability
    axis.text.y = element_text(size = 10),
    strip.text = element_text(size = 10, face = "bold"),
    legend.position = "none",  # Hide legend as reliance rank is already shown in facets
    panel.grid.major = element_line(color = "gray99", size = 0.25),  # Fade out major gridlines
    panel.grid.minor = element_blank()  # Remove minor gridlines
    # panel.grid = element_blank()  # Remove all gridlines

  )

# Load necessary libraries
library(treemapify)
library(ggplot2)

# Prepare data for treemap
treemap_data <- country_reliance_rank %>%
  group_by(Countries) %>%
  mutate(
    total_minerals = sum(count),
    reliance_rank = as.factor(reliance_rank)
  ) %>%
  ungroup()

# Create the treemap
ggplot(treemap_data, aes(
  area = total_minerals,
  fill = reliance_rank,
  label = paste(Countries, "(", total_minerals, ")", sep = "")
)) +
  geom_treemap() +
  geom_treemap_text(
    colour = "white",
    place = "centre",
    grow = TRUE
  ) +
  scale_fill_brewer(palette = "Set3", name = "Reliance Rank") +
  labs(
    title = "Treemap of Reliance Ranks by Country",
    subtitle = "Size represents the number of minerals; color shows reliance rank proportion"
  ) +
  theme_minimal()

# Create a bubble chart
reliance_data %>%
  ggplot(aes(
    x = Net_Import_Reliance_pct_2023,
    y = reorder(Commodity, Net_Import_Reliance_pct_2023),
    size = Net_Import_Reliance_pct_2023,
    color = Net_Import_Reliance_pct_2023
  )) +
  geom_point(alpha = 0.7, size = 1.5) +
  scale_color_gradient(low = "green", high = "red") +
  labs(
    title = "U.S. Net Import Reliance on Critical Minerals (2023)",
    x = "Net Import Reliance (%)",
    y = "Critical Mineral",
    size = "Reliance (%)",
    color = "Reliance (%)"
  ) +
  theme_minimal() +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 5),  # Reduce y-axis font size
    panel.grid.major = element_blank(),   # Remove major gridlines
    panel.grid.minor = element_blank(),   # Remove minor gridlines
    panel.background = element_blank()    # Ensure no background grid
  )

# Create a customized lollipop chart
reliance_data %>%
  ggplot(aes(x = Net_Import_Reliance_pct_2023, y = reorder(Commodity, Net_Import_Reliance_pct_2023))) +
  geom_segment(aes(xend = 0, yend = Commodity), color = "gray") +
  geom_point(aes(color = Net_Import_Reliance_pct_2023), size = 1) +
  scale_color_gradient(low = "green", high = "red") +
  labs(
    title = "Lollipop Chart of U.S. Net Import Reliance on Critical Minerals (2023)",
    x = "Net Import Reliance (%)",
    y = "Critical Mineral",
    color = "Reliance (%)"
  ) +
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 5),  # Reduce y-axis font size
    panel.grid.major = element_blank(),   # Remove major gridlines
    panel.grid.minor = element_blank(),   # Remove minor gridlines
    panel.background = element_blank()    # Ensure no background grid
  )

Major Source Countries for Critical Minerals

This plot shows the number of critical minerals supplied by each country.

# Load the data (update the file path as needed)
source_data <- read.csv("https://raw.githubusercontent.com/hawa1983/DATA-608/refs/heads/main/Story%207/MCS2024_Fig3_Major_Import_Sources.csv")

# Create a bar chart for countries supplying critical minerals
source_data %>%
  arrange(desc(Commodity_Count)) %>%
  ggplot(aes(x = reorder(Country, -Commodity_Count), y = Commodity_Count)) +
  geom_bar(stat = "identity", fill = "#CC6677") +
  coord_flip() +
  labs(
    title = "Major Source Countries for Critical Minerals",
    x = "Country",
    y = "Number of Critical Minerals Supplied"
  ) +
  theme_minimal()

library(dplyr)

library(dplyr)

# Load Data
end_use_data <- read.csv("https://raw.githubusercontent.com/hawa1983/DATA-608/refs/heads/main/Story%207/MCS2024_T4_Critical_Minerals_End_Use.csv")
reliance_data <- read.csv("https://raw.githubusercontent.com/hawa1983/DATA-608/refs/heads/main/Story%207/MCS2024_Fig2_Net_Import_Reliance.csv")

# Print Data Overview
cat("\nMajor Import Source\n")
## 
## Major Import Source
glimpse(commodity_count_data)
## Rows: 43
## Columns: 4
## $ Country         <chr> "Australia", "Austria", "Belarus", "Belgium", "Bolivia…
## $ Commodity_Count <int> 6, 2, 1, 8, 3, 10, 23, 2, 24, 1, 1, 2, 1, 1, 1, 12, 1,…
## $ Map_Class       <fct> 4 to 6, 1 to 3, 1 to 3, 7 to 12, 1 to 3, 7 to 12, 19 t…
## $ Classification  <fct> Ally, Ally, Competitor, Ally, Neutral, Neutral, Ally, …
cat("\nDomestic Production Gap\n")
## 
## Domestic Production Gap
glimpse(domestic_production_gap)
## Rows: 20
## Columns: 14
## $ Source                       <chr> "MCS2024", "MCS2024", "MCS2024", "MCS2024…
## $ Year                         <chr> "2023_estimated", "2023_estimated", "2023…
## $ Critical_mineral             <chr> "Antimony", "Arsenic", "Beryllium", "Bism…
## $ Primary_prod                 <dbl> 0, 0, 190, 0, 0, 500, 0, 0, 0, 0, 17000, …
## $ Secondary_prod               <chr> "4000", NA, NA, "80", "100000", "2100", "…
## $ Apparent_Consuption          <dbl> 22000, 6400, 150, 1400, 380000, 6400, 19,…
## $ Net_Import_Reliance          <chr> "82", "100", NA, "94", "74", "67", "100",…
## $ Primary_import_source        <chr> "China", "China", "Kazakhstan", "China", …
## $ Leading_source_country       <chr> "China", "Peru", "United States", "China"…
## $ Leading_country_prod         <int> 40000, 27000, 190, 16000, 18000000, 17000…
## $ World_total_prod             <int> 83000, 60000, 330, 20000, 41000000, 23000…
## $ World_prod_notes             <chr> "", "Arsenic trioxide.", "", "", "", "", …
## $ Leading_source_precent_world <int> 48, 45, 58, 80, 44, 74, 98, 77, 66, 36, 5…
## $ Shortfall                    <dbl> 22000, 6400, -40, 1400, 380000, 5900, 19,…
cat("\nCritical Minerals End Use\n")
## 
## Critical Minerals End Use
glimpse(end_use_data)
## Rows: 50
## Columns: 4
## $ Source               <chr> "MCS2024", "MCS2024", "MCS2024", "MCS2024", "MCS2…
## $ Critical.Mineral     <chr> "Aluminum", "Antimony", "Arsenic", "Barite", "Ber…
## $ Primary.Applications <chr> "Metallurgy and many sectors of the economy.", "F…
## $ Category_Note        <chr> "", "", "", "", "", "", "Included in the Rare Ear…
cat("\nNet Import Reliance\n")
## 
## Net Import Reliance
glimpse(reliance_data)
## Rows: 63
## Columns: 6
## $ Source                         <chr> "MCS2024", "MCS2024", "MCS2024", "MCS20…
## $ Import_Share_Order             <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, …
## $ Commodity                      <chr> "ARSENIC, all forms", "ASBESTOS", "CESI…
## $ Net_Import_Reliance_pct_2023   <int> 100, 100, 100, 100, 100, 100, 100, 100,…
## $ Major_Import_Sources_2019_2022 <chr> "China, Morocco, Malaysia, Belgium", "B…
## $ Notes                          <chr> "Descending order of import share. Impo…

Visualization of Top Minerals with the Highest Shortfall by Leading Supplier

library(ggplot2)
library(dplyr)
library(janitor)
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
# Clean column names to ensure consistency
domestic_production_gap <- domestic_production_gap %>%
  clean_names() # Standardizes all column names to lowercase with underscores

# Replace NA in leading_source_country with "Unknown"
domestic_production_gap <- domestic_production_gap %>%
  mutate(leading_source_country = ifelse(is.na(leading_source_country), "Unknown", leading_source_country))

# Verify the correct column name
top_shortfall <- domestic_production_gap %>%
  arrange(desc(shortfall)) %>%   # Use cleaned column names (all lowercase)
  slice(1:10)

# Plotting
ggplot(top_shortfall, aes(x = reorder(critical_mineral, -shortfall), y = shortfall, fill = leading_source_country)) +
  geom_bar(stat = "identity") +
  coord_flip() +
  labs(
    title = "Top Minerals with the Highest Shortfall",
    subtitle = "Highlighting Leading Suppliers",
    x = "Critical Mineral",
    y = "Shortfall (Metric Tons)",
    fill = "Leading Supplier"
  ) +
  theme_minimal()

Visualization of Net Import Reliance Distribution

This shows the distribution of Net_Import_Reliance_pct_2023 for critical minerals.

ggplot(reliance_data, aes(x = Net_Import_Reliance_pct_2023)) +
  geom_histogram(binwidth = 10, fill = "skyblue", color = "black") +
  labs(
    title = "Distribution of Net Import Reliance for Critical Minerals",
    x = "Net Import Reliance (%)",
    y = "Frequency"
  ) +
  theme_minimal()

Visualization of Top Supplying Countries by Mineral Count and Classification

This highlights countries supplying the most minerals categorized as Ally, Competitor, or Neutral.

top_countries <- commodity_count_data %>%
  arrange(desc(Commodity_Count)) %>%
  slice(1:10)

ggplot(top_countries, aes(x = reorder(Country, Commodity_Count), y = Commodity_Count, fill = Classification)) +
  geom_bar(stat = "identity") +
  coord_flip() +
  scale_fill_manual(values = c("Ally" = "green", "Competitor" = "red", "Neutral" = "blue")) +
  labs(
    title = "Top Supplying Countries by Mineral Count",
    x = "Country",
    y = "Number of Critical Minerals Supplied",
    fill = "Country Classification"
  ) +
  theme_minimal()

Conclusion Slide

# Load Required Libraries
library(ggplot2)
library(dplyr)
library(janitor)
library(rnaturalearth)
library(rnaturalearthdata)
## 
## Attaching package: 'rnaturalearthdata'
## The following object is masked from 'package:rnaturalearth':
## 
##     countries110
library(sf)
## Linking to GEOS 3.12.2, GDAL 3.9.3, PROJ 9.4.1; sf_use_s2() is TRUE
# Step 1: Data Cleaning ---------------------------------------------------
# Clean column names and net_import_reliance
domestic_production_gap <- domestic_production_gap %>% 
  clean_names() %>%
  mutate(
    net_import_reliance = as.numeric(gsub("[<>]", "", net_import_reliance)),
    net_import_reliance = ifelse(is.na(net_import_reliance), 0, net_import_reliance),
    shortfall = ifelse(is.na(shortfall), 0, shortfall),
    leading_source_country = ifelse(is.na(leading_source_country), "Unknown", leading_source_country)
  )

# Step 2: Aggregate Data --------------------------------------------------
country_summary <- domestic_production_gap %>%
  group_by(leading_source_country) %>%
  summarize(
    total_shortfall = sum(shortfall, na.rm = TRUE),
    average_reliance = mean(net_import_reliance, na.rm = TRUE)
  )

# Step 3: Prepare World Map -----------------------------------------------
# Load world map
world <- map_data("world")

# Add the U.S. as Importer and classify other suppliers
geo_data <- country_summary %>%
  bind_rows(data.frame(
    leading_source_country = "USA",
    total_shortfall = NA,
    average_reliance = NA,
    Classification = "Importer"
  )) %>%
  mutate(
    Classification = case_when(
      leading_source_country %in% c("China", "Russia") ~ "Competitor",
      leading_source_country %in% c("Canada", "Australia") ~ "Ally",
      leading_source_country %in% c("Brazil", "South Africa") ~ "Other Supplier",
      is.na(Classification) ~ "Other Supplier",
      TRUE ~ Classification
    )
  )

# Merge with world map data
world_map <- world %>%
  left_join(geo_data, by = c("region" = "leading_source_country")) %>%
  mutate(Classification = replace_na(Classification, "Not a Supplier"))

# Add longitude/latitude centroids for bubbles
bubble_data <- world_map %>%
  group_by(region) %>%
  summarize(
    long = mean(long, na.rm = TRUE),
    lat = mean(lat, na.rm = TRUE),
    average_reliance = mean(average_reliance, na.rm = TRUE)
  ) %>%
  filter(!is.na(average_reliance))

# Step 4: Plot the Map with Bubbles ---------------------------------------
ggplot(world_map, aes(x = long, y = lat, group = group, fill = Classification)) +
  # Country polygons
  geom_polygon(color = "white") +
  # Add bubbles (remove size legend explicitly)
  geom_point(data = bubble_data, aes(x = long, y = lat, color = average_reliance, size = average_reliance),
             inherit.aes = FALSE, show.legend = c(color = TRUE, size = FALSE)) +
  # Scales
  scale_fill_manual(
    values = c(
      "Importer" = "#F0C808",
      "Ally" = "#117733",
      "Competitor" = "#CC6677",
      "Neutral" = "#88CCEE",
      "Other Supplier" = "#9467BD",
      "Not a Supplier" = "lightgrey"
    ),
    name = "Country Classification"
  ) +
  scale_color_viridis_c(name = "Average Net Import\nReliance (%)") +
  # Labels
  labs(
    title = "Global Suppliers of Critical Minerals with U.S. as Importer",
    subtitle = "Classified by Role and Net Import Reliance",
    caption = "Data Source: USGS Mineral Commodity Summaries 2024"
  ) +
  # Theme adjustments
  theme_minimal() +
  theme(
    axis.text = element_blank(),        
    axis.ticks = element_blank(),       
    axis.title = element_blank(),       
    panel.grid = element_blank(),       
    legend.position = "right"
  )

Transition Slides

# Load Libraries
library(ggplot2)
library(dplyr)
library(tidyr)
library(maps)
library(gridExtra)
## 
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
## 
##     combine
library(grid)
library(ggrepel)

# Simulated Data ----------------------------------------------------------
# Bar Chart Data (Applications of Critical Minerals)
bar_data <- data.frame(
  Category = c("Aerospace &\n Defense", "Batteries & Energy", 
               "Catalysts & Industrial", "Electronics & Optics",
               "Magnets & Lasers", "Steelmaking &\n Alloys"),
  Count = c(8, 12, 9, 11, 7, 10),
  Color = c("#1f78b4", "#ff7f00", "#e31a1c", "#6a3d9a", "#33a02c", "#b2df8a")
)

# World Map Data for Supplier Classification
world <- map_data("world")
supplier_regions <- data.frame(
  region = c("USA", "China", "Russia", "Australia", "Brazil", "India"),
  Classification = c("Ally", "Competitor", "Competitor", "Ally", "Other Supplier", "Neutral")
)

# Merge Supplier Data with Map
world_map <- world %>%
  left_join(supplier_regions, by = "region") %>%
  mutate(Classification = replace_na(Classification, "Not a Supplier"))

# Chemical Symbols for Scattering
set.seed(123) # Reproducibility
chemical_symbols <- data.frame(
  symbol = sample(c("Al", "Sb", "As", "B", "Be", "Bi", "Ce", "Cs", "Co", 
                    "Cr", "Cu", "Dy", "Er", "Eu", "F", "Gd", "Ga", "Ge",
                    "Hf", "Ho", "In", "Ir", "La", "Li", "Mg", "Mn", "Nd", 
                    "Ni", "Nb", "Pd", "Pt", "Pr", "Rh", "Ru", "Sm", "Sc",
                    "Ta", "Te", "Tb", "Tm", "Sn", "Ti", "W", "V", "Yb", 
                    "Y", "Zn", "Zr"), 50, replace = TRUE),
  x = runif(50, 0, 1),
  y = runif(50, 0, 1),
  color = sample(colors(), 50)
)

# Plot 1: Bar Chart -------------------------------------------------------
bar_chart <- ggplot(bar_data, aes(x = Category, y = Count, fill = Category)) +
  geom_bar(stat = "identity", width = 0.7) +
  geom_text(aes(label = Category, size = Count, color = Color), 
            position = position_stack(vjust = 1.05), 
            hjust = 0.5, fontface = "bold") +
  scale_fill_manual(values = bar_data$Color) +
  scale_color_identity() +
  scale_size_continuous(range = c(3, 10)) +
  theme_void() +
  theme(legend.position = "none")

# Plot 2: World Map -------------------------------------------------------
map_plot <- ggplot(world_map, aes(x = long, y = lat, group = group, fill = Classification)) +
  geom_polygon(color = "white") +
  scale_fill_manual(values = c(
    "Ally" = "#117733",
    "Competitor" = "#CC6677",
    "Neutral" = "#88CCEE",
    "Other Supplier" = "#9467BD",
    "Not a Supplier" = "lightgrey"
  )) +
  theme_void() +
  theme(legend.position = "none")

# Overlay Chemical Symbols ------------------------------------------------
scatter_plot <- ggplot() +
  geom_text(data = chemical_symbols, 
            aes(x = x, y = y, label = symbol, color = color), 
            size = 6, fontface = "bold") +
  scale_color_identity() +
  theme_void()

# Combine Plots -----------------------------------------------------------
grid.arrange(
  bar_chart,
  map_plot,
  scatter_plot,
  ncol = 1,
  heights = c(3, 3, 1)
)

# Load Libraries
library(ggplot2)
library(dplyr)
library(tidyr)
library(maps)
library(gridExtra)
library(grid)
library(ggrepel)

# Simulated Data ----------------------------------------------------------
# Bar Chart Data (Applications of Critical Minerals)
bar_data <- data.frame(
  Category = c("Aerospace &\nDefense", "Batteries & Energy", 
               "Catalysts & Industrial", "Electronics & Optics",
               "Magnets & Lasers", "Steelmaking &\nAlloys"),
  Count = c(8, 12, 9, 11, 7, 10),
  Color = c("#1f78b4", "#ff7f00", "#e31a1c", "#6a3d9a", "#33a02c", "#b2df8a")
)

# World Map Data for Supplier Classification
world <- map_data("world")
supplier_regions <- data.frame(
  region = c("USA", "China", "Russia", "Australia", "Brazil", "India"),
  Classification = c("Ally", "Competitor", "Competitor", "Ally", "Other Supplier", "Neutral")
)

# Merge Supplier Data with Map
world_map <- world %>%
  left_join(supplier_regions, by = "region") %>%
  mutate(Classification = replace_na(Classification, "Not a Supplier"))

# Chemical Symbols for Scattering (Now scaled to the map area)
set.seed(123) # Reproducibility
chemical_symbols <- data.frame(
  symbol = sample(c("Al", "Sb", "As", "B", "Be", "Bi", "Ce", "Cs", "Co", 
                    "Cr", "Cu", "Dy", "Er", "Eu", "F", "Gd", "Ga", "Ge",
                    "Hf", "Ho", "In", "Ir", "La", "Li", "Mg", "Mn", "Nd", 
                    "Ni", "Nb", "Pd", "Pt", "Pr", "Rh", "Ru", "Sm", "Sc",
                    "Ta", "Te", "Tb", "Tm", "Sn", "Ti", "W", "V", "Yb", 
                    "Y", "Zn", "Zr"), 50, replace = TRUE),
  long = runif(50, -180, 180),
  lat = runif(50, -60, 80),
  color = sample(colors(), 50)
)

# Plot 1: Bar Chart -------------------------------------------------------
bar_chart <- ggplot(bar_data, aes(x = Category, y = Count, fill = Category)) +
  geom_bar(stat = "identity", width = 0.7) +
  geom_text(aes(label = gsub("&", "and", Category), color = Color, size = Count), 
            position = position_stack(vjust = 1.4), 
            fontface = "bold", hjust = 0.5) +
  scale_fill_manual(values = bar_data$Color) +
  scale_color_identity() +
  scale_size_continuous(range = c(3, 8)) +
  theme_void() +
  theme(legend.position = "none")

# Plot 2: World Map -------------------------------------------------------
map_plot <- ggplot(world_map, aes(x = long, y = lat, group = group, fill = Classification)) +
  geom_polygon(color = "white") +
  scale_fill_manual(values = c(
    "Ally" = "#117733",
    "Competitor" = "#CC6677",
    "Neutral" = "#88CCEE",
    "Other Supplier" = "#9467BD",
    "Not a Supplier" = "lightgrey"
  )) +
  theme_void() +
  theme(legend.position = "none")

# Plot 3: Chemical Symbols Scattered --------------------------------------
scatter_plot <- ggplot() +
  geom_text(data = chemical_symbols, 
            aes(x = long, y = lat, label = symbol, color = color), 
            size = 5, fontface = "bold") +
  scale_color_identity() +
  theme_void()

# Combine Plots -----------------------------------------------------------
grid.arrange(
  bar_chart,
  map_plot,
  scatter_plot,
  ncol = 1,
  heights = c(3, 3, 3)
)

# Load Libraries
library(ggplot2)
library(dplyr)
library(tidyr)
library(gridExtra)
library(grid)
library(maps)
library(ggrepel)

# Simulated Data ----------------------------------------------------------
# Data for Sources - Bar Chart
sources_data <- data.frame(
  Source = c("Recycling", "Domestic Mining", "Imports"),
  Count = c(15, 10, 25),
  Color = c("#1f78b4", "#33a02c", "#e31a1c")
)

# World Map Data for Supplier Roles
world <- map_data("world")
supplier_roles <- data.frame(
  region = c("USA", "China", "Russia", "Australia", "Brazil", "India"),
  Classification = c("Ally", "Competitor", "Competitor", "Ally", "Other Supplier", "Neutral")
)

# Merge Supplier Data with Map
world_map <- world %>%
  left_join(supplier_roles, by = "region") %>%
  mutate(Classification = replace_na(Classification, "Not a Supplier"))

# Scatter Chemical Symbols
set.seed(123)
chemical_symbols <- data.frame(
  symbol = sample(c("Al", "Co", "Ni", "Li", "Mn", "Cr", "Zn", "Be", "Nd", "W", "Y", "Pt", "Nb"), 30, replace = TRUE),
  x = runif(30, 0, 1),
  y = runif(30, 0, 1),
  color = sample(colors(), 30)
)

# Plot 1: Bar Chart - Sources --------------------------------------------
sources_plot <- ggplot(sources_data, aes(x = Source, y = Count, fill = Source)) +
  geom_bar(stat = "identity", width = 0.6) +
  geom_text(aes(label = Source, size = Count), position = position_stack(vjust = 0.9), 
            color = "white", fontface = "bold") +
  scale_fill_manual(values = sources_data$Color) +
  scale_size_continuous(range = c(3, 8)) +
  theme_void() +
  theme(legend.position = "none")

# Plot 2: World Map - Supplier Roles --------------------------------------
map_plot <- ggplot(world_map, aes(x = long, y = lat, group = group, fill = Classification)) +
  geom_polygon(color = "white") +
  scale_fill_manual(values = c(
    "Ally" = "#117733",
    "Competitor" = "#CC6677",
    "Neutral" = "#88CCEE",
    "Other Supplier" = "#9467BD",
    "Not a Supplier" = "lightgrey"
  )) +
  theme_void() +
  theme(legend.position = "bottom")

# Plot 3: Scatter Symbols - Conclusion ------------------------------------
scatter_plot <- ggplot() +
  geom_text(data = chemical_symbols, aes(x = x, y = y, label = symbol, color = color),
            size = 6, fontface = "bold") +
  scale_color_identity() +
  theme_void()

# Combine All Plots -------------------------------------------------------
grid.arrange(
  sources_plot,       # Top Section: Sources
  map_plot,           # Middle Section: Suppliers & Vulnerabilities
  scatter_plot,       # Bottom Section: Conclusion
  ncol = 1,
  heights = c(2, 3, 2)
)

# Load Libraries
library(ggplot2)
library(dplyr)
library(tidyr)
library(maps)
library(gridExtra)
library(grid)
library(ggrepel)

# Simulated Data ----------------------------------------------------------
# Bar Chart Data (Applications of Critical Minerals)
bar_data <- data.frame(
  Category = c("Aerospace & Defense", "Batteries & Energy", 
               "Catalysts & Industrial", "Electronics & Optics",
               "Magnets & Lasers", "Steelmaking & Alloys"),
  Count = c(60, 88, 75, 90, 82, 75),
  Color = c("#6a3d9a", "#ff7f00", "#1f78b4", "#33a02c", "#e31a1c", "#b2df8a"),
  x = c(1, 2, 3, 4, 5, 6)
)

# World Map Data for Supplier Classification
world <- map_data("world")
supplier_regions <- data.frame(
  region = c("USA", "China", "Russia", "Australia", "Brazil", "India"),
  Classification = c("Ally", "Competitor", "Competitor", "Ally", "Other Supplier", "Neutral")
)

# Merge Supplier Data with Map
world_map <- world %>%
  left_join(supplier_regions, by = "region") %>%
  mutate(Classification = replace_na(Classification, "Not a Supplier"))

# Scatter Words -----------------------------------------------------------
set.seed(123) # For reproducibility
words_data <- data.frame(
  word = c("Applications", "Supply", "Demand", "Imbalance"),
  x = runif(20, 0.5, 6.5), # Random x positions
  y = runif(20, 5, 20),    # Random y positions
  color = sample(colors(), 20)
)

# Plot 1: Bar Chart with Numbers ------------------------------------------
bar_chart <- ggplot(bar_data, aes(x = factor(x), y = Count, fill = Category)) +
  geom_bar(stat = "identity", width = 0.7) +
  geom_text(aes(label = paste0(Count, "%"), y = Count / 2), # Place numbers at centroid
            size = 6, fontface = "bold", color = "black") +
  scale_fill_manual(values = bar_data$Color) +
  theme_void() +
  theme(legend.position = "none")

# Plot 2: World Map -------------------------------------------------------
map_plot <- ggplot(world_map, aes(x = long, y = lat, group = group, fill = Classification)) +
  geom_polygon(color = "white") +
  scale_fill_manual(values = c(
    "Ally" = "#117733",
    "Competitor" = "#CC6677",
    "Neutral" = "#88CCEE",
    "Other Supplier" = "#9467BD",
    "Not a Supplier" = "lightgrey"
  )) +
  theme_void() +
  theme(legend.position = "none")

# Overlay Words -----------------------------------------------------------
words_plot <- ggplot() +
  geom_text(data = words_data, 
            aes(x = x, y = y, label = word, color = color), 
            size = 6, fontface = "bold", angle = sample(c(-30, 0, 30), 20, replace = TRUE)) +
  scale_color_identity() +
  theme_void()

# Combine Plots -----------------------------------------------------------
grid.arrange(
  bar_chart,
  map_plot,
  words_plot,
  ncol = 1,
  heights = c(3, 3, 1)
)