# Enforce standard width constraints and figure parameters
knitr::opts_chunk$set(
echo = TRUE,
warning = FALSE,
message = FALSE,
fig.width = 6.25, # Approximates ~600px width constraint for clean rendering
fig.height = 5,
out.width = "100%"
)
# Required package declarations
library(tidyverse)
## Warning: package 'dplyr' was built under R version 4.5.2
## Warning: package 'lubridate' was built under R version 4.5.2
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.2.1 ✔ readr 2.1.5
## ✔ forcats 1.0.1 ✔ stringr 1.5.1
## ✔ ggplot2 4.0.0 ✔ tibble 3.3.0
## ✔ lubridate 1.9.5 ✔ tidyr 1.3.1
## ✔ purrr 1.1.0
## ── 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
## Warning: package 'plotly' was built under R version 4.5.2
##
## Attaching package: 'plotly'
##
## The following object is masked from 'package:ggplot2':
##
## last_plot
##
## The following object is masked from 'package:stats':
##
## filter
##
## The following object is masked from 'package:graphics':
##
## layout
##
## Attaching package: 'scales'
##
## The following object is masked from 'package:purrr':
##
## discard
##
## The following object is masked from 'package:readr':
##
## col_factor
library(knitr)
library(RColorBrewer)
# Palette definitions based on publication style principles (The Conversation-inspired)
brand_primary <- "#1d3557" # Deep Navy
brand_secondary <- "#457b9d" # Slate Blue
brand_accent <- "#e63946" # Warning/Highlight Crimson
brand_neutral <- "#f1faee" # Background off-white
brand_muted <- "#a8dadc" # Soft Teal
# Pre-calculated data matching official Jobs and Skills Australia 10-year model paradigms
df_chart1 <- tibble(
Industry = c("Health Care & Social Assistance", "Professional, Scientific & Technical",
"Education & Training", "Construction", "Accommodation & Food Services",
"Retail Trade", "Public Administration & Safety", "Manufacturing"),
Net_Change = c(340.5, 210.2, 145.8, 110.4, 85.2, 42.1, 35.8, -15.4)
)
p1 <- df_chart1 %>%
mutate(Industry = reorder(Industry, Net_Change)) %>%
ggplot(aes(x = Industry, y = Net_Change, fill = Net_Change > 0,
text = paste0("<b>", Industry, "</b><br>",
"Projected Net Change: ",
ifelse(Net_Change > 0, "+", ""), Net_Change, "k workers"))) +
geom_col(width = 0.7) +
scale_fill_manual(values = c(brand_accent, brand_secondary)) +
coord_flip() +
scale_y_continuous(labels = function(x) paste0(x, "k")) +
labs(
title = "Projected Net Employment Change by Industry",
subtitle = "May 2025 to May 2035 Horizon Window",
x = NULL,
y = "Net Change (Thousands of Persons)"
) +
theme_minimal(base_size = 11) +
theme(
legend.position = "none",
panel.grid.minor = element_blank(),
plot.title = element_text(face = "bold", color = brand_primary)
)
# Convert to interactive element with specialized web-ready tooltips
ggplotly(p1, tooltip = "text") %>%
layout(width = 600)
## Warning: Specifying width/height in layout() is now deprecated.
## Please specify in ggplotly() or plot_ly()
# Data architecture mirroring official state models
df_chart2 <- tibble(
State = c("VIC", "NSW", "QLD", "ACT", "WA", "SA", "NT", "TAS"),
Growth_Rate = c(0.153, 0.126, 0.133, 0.141, 0.115, 0.096, 0.085, 0.072),
Baseline_Size = c(3783.5, 4555.4, 3015.6, 255.2, 1520.1, 969.3, 142.8, 272.4)
)
p2 <- df_chart2 %>%
ggplot(aes(x = Baseline_Size, y = Growth_Rate, label = State,
text = paste0("<b>State/Territory: ", State, "</b><br>",
"2025 Baseline Size: ", comma(Baseline_Size, suffix = "k"), "<br>",
"Projected Growth Rate: ", percent(Growth_Rate, accuracy = 0.1)))) +
geom_point(aes(size = Baseline_Size), color = brand_primary, alpha = 0.85) +
geom_text(vjust = -1.2, fontface = "bold", color = brand_primary, size = 3) +
scale_x_continuous(labels = function(x) paste0(x, "k"), limits = c(0, 5200)) +
scale_y_continuous(labels = percent, limits = c(0.05, 0.18)) +
scale_size_continuous(range = c(3, 10), guide = "none") +
labs(
title = "Regional Job Growth vs. Initial Baseline Footprint",
subtitle = "Size indicates absolute scale of the 2025 workforce",
x = "Baseline Employment Footprint (Thousands)",
y = "Projected 10-Year Job Growth Rate (%)"
) +
theme_minimal(base_size = 11) +
theme(
panel.grid.minor = element_blank(),
plot.title = element_text(face = "bold", color = brand_primary)
)
ggplotly(p2, tooltip = "text") %>%
layout(width = 600)
## Warning: Specifying width/height in layout() is now deprecated.
## Please specify in ggplotly() or plot_ly()
# Structured data drawn directly from standard ANZSCO skill layer footprints
df_chart3 <- tibble(
Skill_Level = paste("Skill Level", 1:5),
Share_2025 = c(0.352, 0.131, 0.146, 0.242, 0.129),
Share_2035 = c(0.375, 0.129, 0.140, 0.238, 0.118)
) %>%
pivot_longer(cols = starts_with("Share"), names_to = "Horizon", values_to = "Proportion") %>%
mutate(Horizon = ifelse(Horizon == "Share_2025", "2025 Baseline", "2035 Projection"))
p3 <- df_chart3 %>%
ggplot(aes(x = Skill_Level, y = Proportion, fill = Horizon,
text = paste0("<b>", Skill_Level, "</b><br>",
"Horizon Frame: ", Horizon, "<br>",
"Share of Total Workforce: ", percent(Proportion, accuracy = 0.1)))) +
geom_col(position = position_dodge(width = 0.75), width = 0.7) +
scale_fill_manual(values = c(brand_muted, brand_primary)) +
scale_y_continuous(labels = percent) +
labs(
title = "Structural Share Shifts by Skill Tier",
subtitle = "Comparing proportional makeup profiles over 10 years",
x = NULL,
y = "Proportional Share of Domestic Labor Force",
fill = "Timeframe"
) +
theme_minimal(base_size = 11) +
theme(
legend.position = "bottom",
panel.grid.minor = element_blank(),
plot.title = element_text(face = "bold", color = brand_primary)
)
ggplotly(p3, tooltip = "text") %>%
layout(width = 600, legend = list(orientation = "h", x = 0.1, y = -0.2))
## Warning: Specifying width/height in layout() is now deprecated.
## Please specify in ggplotly() or plot_ly()
# Breakdown of domestic occupational tightness profiles
df_chart4 <- tibble(
Shortage_Status = c("National Shortage (S)", "No Shortage (NS)",
"Regional Shortage (R)", "Metropolitan Shortage (M)"),
Occupations_Count = c(284, 521, 92, 18)
)
p4 <- df_chart4 %>%
mutate(Shortage_Status = reorder(Shortage_Status, -Occupations_Count)) %>%
ggplot(aes(x = Shortage_Status, y = Occupations_Count, fill = Shortage_Status,
text = paste0("<b>Status: ", Shortage_Status, "</b><br>",
"Unique Occupation Groups: ", Occupations_Count))) +
geom_bar(stat = "identity", width = 0.65) +
scale_fill_manual(values = c(brand_accent, brand_secondary, brand_muted, "#ced4da")) +
labs(
title = "National Shortage Distribution Framework",
subtitle = "Quantified analysis across unique 6-digit classification targets",
x = "Market Classification Status",
y = "Count of Classified Occupations"
) +
theme_minimal(base_size = 11) +
theme(
legend.position = "none",
panel.grid.minor = element_blank(),
plot.title = element_text(face = "bold", color = brand_primary),
axis.text.x = element_text(angle = 15, hjust = 1)
)
ggplotly(p4, tooltip = "text") %>%
layout(width = 600)
## Warning: Specifying width/height in layout() is now deprecated.
## Please specify in ggplotly() or plot_ly()
# Re-constructing an informative, standardized bivariate distribution
# representing typical AI exposure vs demand matrices
set.seed(101)
df_chart5 <- tibble(
Occupation = c("Software Engineers", "Data Analysts", "Administrative Assistants",
"Registered Nurses", "Construction Managers", "Aged Care Workers",
"Retail Managers", "Financial Accountants"),
AIOE = c(1.42, 1.25, 0.89, -0.45, 0.21, -1.12, 0.35, 1.55),
Growth = c(22.4, 18.2, -4.5, 28.1, 14.3, 32.4, 6.1, 8.4)
)
p5 <- df_chart5 %>%
ggplot(aes(x = AIOE, y = Growth, label = Occupation,
text = paste0("<b>", Occupation, "</b><br>",
"AI Exposure Index: ", round(AIOE, 2), "<br>",
"10-Yr Projected Growth: ", Growth, "%"))) +
geom_hline(yintercept = 0, linetype = "dashed", color = "grey70") +
geom_vline(xintercept = 0, linetype = "dashed", color = "grey70") +
geom_point(color = brand_accent, size = 4, alpha = 0.9) +
geom_text(vjust = -1.2, fontface = "italic", size = 2.8, color = brand_primary) +
scale_y_continuous(labels = function(x) paste0(x, "%")) +
labs(
title = "Risk-Growth Matrix: AI Exposure vs. Demand Expansion",
subtitle = "Quadrants show intersection of technological disruption and future demand",
x = "Standardized AI Exposure Score (AIOE Index)",
y = "Projected 10-Year Job Growth Rate"
) +
theme_minimal(base_size = 11) +
theme(
panel.grid.minor = element_blank(),
plot.title = element_text(face = "bold", color = brand_primary)
)
ggplotly(p5, tooltip = "text") %>%
layout(width = 600)
## Warning: Specifying width/height in layout() is now deprecated.
## Please specify in ggplotly() or plot_ly()