Artificial intelligence is transforming the global workforce at an unprecedented rate. Certain job roles are experiencing considerable disruption due to automation, while others remain comparatively resilient. Similar to historical technological advancements such as the printing press, electricity, and computers, some positions will inevitably be replaced by AI-driven processes; however, concerns regarding AI may surpass its actual impact.
The visualizations in this report are organized examine the different aspects of the impact of AI. The visualizations begin with an analysis of roles most susceptible to automation, proceed to examine global trends in AI adoption and skill demand, and conclude by evaluating the implications of AI-induced change on US salaries in comparison to those in other countries.
# Import all required libraries once at the top
import pandas as pd
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.ticker import FuncFormatter
import seaborn as sns
import plotly.graph_objects as go
import plotly.io as pio
import warnings
warnings.filterwarnings("ignore")
# Define file path and read in the dataset into a single dataframe
path = "C:/Users/reyes/lum_python/"
filename = path + "ai_job_replacement_2020_2026_v2.csv"
df = pd.read_csv(filename)
This report analyzes the AI Job Replacement dataset spanning approximately a 7 year period (2020-2026) and covers ten distinct job roles across nine countries: Australia, Brazil, Canada, Germany, India, Japan, Singapore, the United Kingdom, and the United States.
The dataset captures key workforce metrics including automation risk, AI replacement scores, skill demand growth, AI adoption levels, and salary changes following AI adoption.
The findings provided are based on a sample dataset; however, the descriptive analysis is intended to depict multiple relationships between the variables collected. The visualizations begin with a broad view of which job roles carry the highest automation risk, then examine how aggressively AI is projected to replace workers across roles and years, identify how countries compare in skill demand growth and AI adoption, explore how adoption levels vary across job roles, and finally place US salaries side-by-side against the global average to assess the compensation impact of AI-driven change.
The scatterplot below illustrates the average automation risk (%) for each job role between 2020 and 2026. Each diamond represents a specific job in a particular year. Both color and size indicate risk: red and larger diamonds mean higher automation risk, while green and smaller ones point to lower risk. Job roles are arranged on the y-axis based on their average risk, from lowest to highest.
# Group by year and job role, then calculate the average automation risk per group
grp = df.groupby(['year', 'job_role'])['automation_risk_percent'].mean().reset_index()
grp.columns = ['year', 'job_role', 'avg_risk']
# Rescale the risk value for marker size — larger markers highlight higher-risk roles
grp['risk_scaled'] = round(grp['avg_risk'], 0) * 7
# Rank job roles by their overall average automation risk across all years in ascending order
risk_order = (
df.groupby('job_role')['automation_risk_percent']
.mean()
.sort_values(ascending=True)
.index
.tolist()
)
# job_roles holds the ordered list used for both the mapping and the y-axis tick labels
# job_map assigns a numeric position to each role so the y-axis sorts by risk (low to high)
job_roles = risk_order
job_map = {role: i for i, role in enumerate(job_roles)}
grp['job_num'] = grp['job_role'].map(job_map)
# Each marker = one job role in one year; color and size encode automation risk %
# Red = higher risk, Green = lower risk (RdYlGn_r colormap)
plt.figure(figsize=(16, 8))
plt.scatter(grp['year'], grp['job_num'], c=grp['avg_risk'], s=grp['risk_scaled'],
cmap='RdYlGn_r', edgecolors='black', linewidths=0.6, marker='D', alpha=0.85)
_ = plt.title('Average Automation Risk (%) per Year by Job Role (2020-2026)', fontsize=18)
_ = plt.xlabel('Year', fontsize=14)
_ = plt.ylabel('Job Role', fontsize=14)
my_x_ticks = [*range(grp['year'].min(), grp['year'].max() + 1, 1)]
_ = plt.xticks(my_x_ticks, fontsize=13, color='black')
_ = plt.yticks([*range(len(job_roles))], job_roles, fontsize=13, color='black')
cbar = plt.colorbar()
_ = cbar.set_label('Avg Automation Risk (%)', rotation=270, fontsize=14, color='black', labelpad=30)
risk_min = int(grp['avg_risk'].min())
risk_max = int(grp['avg_risk'].max()) + 1
cbar_ticks = [*range(risk_min, risk_max, 5)]
_ = cbar.set_ticks(cbar_ticks)
cbar.ax.tick_params(labelsize=11)
plt.tight_layout()
plt.show()
Truck Driver and Customer Support Rep consistently face the greatest risk of automation during this period. Ironically, the roles that are typically identified as replacable by AI; Software Engineer and Data Analyst, regularly show the lowest risk scores. Risk levels do not change much year to year, implying that how vulnerable a role is to automation depends more on the job’s nature than on the increase of AI in the global econonomy.
The heatmap below shows the average AI replacement score for each job role from 2020 to 2026. Unlike the automation risk scatterplot, it reveals not only which positions are susceptible to automation but also the anticipated intensity of AI-driven worker displacement. Warmer colors (red) indicate higher replacement scores; cooler colors (blue) indicate lower scores.
# Build pivot table for the heatmap
# Rows (y-axis) = year, Columns (x-axis) = job_role, Values = avg AI replacement score
hm_df = (
df.groupby(["year", "job_role"])["ai_replacement_score"]
.mean()
.reset_index(name="avg_ai_replacement")
)
hm_df = hm_df.pivot(index="year", columns="job_role", values="avg_ai_replacement")
hm_df.columns.name = None
fig = plt.figure(figsize=(14, 10))
ax = fig.add_subplot(1, 1, 1)
decimal_fmt = FuncFormatter(lambda x, p: f"{x:.1f}")
ax = sns.heatmap(
hm_df,
linewidth=0.2,
annot=True,
cmap="coolwarm",
fmt=".1f",
square=True,
annot_kws={"size": 11},
cbar_kws={"format": decimal_fmt, "orientation": "vertical"}
)
_ = plt.title("Average AI Replacement Score by Job Role and Year (2020-2026)", fontsize=18, pad=15)
_ = plt.xlabel("Job Role", fontsize=16, labelpad=10)
_ = plt.ylabel("Year", fontsize=16, labelpad=10)
_ = plt.yticks(rotation=0, size=13)
_ = plt.xticks(rotation=30, horizontalalignment="right", size=12)
ax.invert_yaxis()
cbar = ax.collections[0].colorbar
score_min = hm_df.to_numpy().min()
score_max = hm_df.to_numpy().max()
my_colorbar_ticks = [round(v, 1) for v in [score_min + i * (score_max - score_min) / 5
for i in range(6)]]
_ = cbar.set_ticks(my_colorbar_ticks)
_ = cbar.set_ticklabels([f"{v:.1f}" for v in my_colorbar_ticks])
_ = cbar.set_label("Avg AI Replacement Score", rotation=270, fontsize=14, color="black", labelpad=20)
plt.tight_layout()
plt.show()
The heatmap reinforces the findings from the scatterplot. Truck Driver and Customer Support Rep have the darkest red cells across nearly every year. A notable observation is that Customer Support Rep’s replacement score spiked in 2026, reaching its highest value in the dataset. This may reflect the growing maturity of AI-powered customer service tools in the form of sophisticated chatbots in recent years. Software Engineer and Data Analyst remain the most resilient roles throughout the period.
After identifying the roles most at risk, the next step was to examine how different countries are responding to AI. The horizontal bar chart below displays each country’s average skill demand growth (%) alongside its average AI adoption level, using a dual-axis design: steel blue bars show skill demand growth (bottom axis, 0-7), while coral bars indicate AI adoption levels (top axis, 0-60).
# Compute the average skill demand growth % and average AI adoption level per country
# Sorted alphabetically by country name
dual_df = (
df.groupby("country")
.agg(
avg_demand_growth=("skill_demand_growth_percent", "mean"),
avg_ai_adoption=("ai_adoption_level", "mean")
)
.reset_index()
)
dual_df = dual_df.sort_values("country").reset_index(drop=True)
# Function to add data labels to the right of each horizontal bar
def autolabel(these_bars, this_ax, place_of_decimals, symbol):
for each_bar in these_bars:
width = each_bar.get_width()
this_ax.text(width * 1.01, each_bar.get_y() + each_bar.get_height() / 2,
symbol + format(width, place_of_decimals),
fontsize=11, color='black', ha='left', va='center')
# Dual axis horizontal bar chart
# twiny() creates a shared y-axis with two independent x-axes
fig = plt.figure(figsize=(14, 10))
ax1 = fig.add_subplot(1, 1, 1)
ax2 = ax1.twiny()
bar_width = 0.4
y_pos = np.arange(len(dual_df))
# Bottom axis: average skill demand growth % — steel blue bars
demand_bars = ax1.barh(y_pos - (0.5 * bar_width), dual_df["avg_demand_growth"], bar_width,
color="steelblue", edgecolor="black", label="Avg Skill Demand Growth %")
# Top axis: average AI adoption level — coral bars
adoption_bars = ax2.barh(y_pos + (0.5 * bar_width), dual_df["avg_ai_adoption"], bar_width,
color="coral", edgecolor="black", label="Avg AI Adoption Level")
_ = ax1.set_ylabel("Country", fontsize=18)
_ = ax1.set_xlabel("Avg Skill Demand Growth (%)", fontsize=14, labelpad=12)
_ = ax2.set_xlabel("Avg AI Adoption Level", fontsize=14, labelpad=12)
ax1.tick_params(axis="x", labelsize=13)
ax2.tick_params(axis="x", labelsize=13)
_ = plt.title("Avg Skill Demand Growth % and AI Adoption Level by Country", fontsize=18, pad=40)
_ = ax1.set_yticks(y_pos)
_ = ax1.set_yticklabels(dual_df["country"], fontsize=13)
# Set x-axis limits to reduce empty space
_ = ax1.set_xlim(0, 7)
_ = ax2.set_xlim(0, 60)
# Legend positioned beside the title to avoid covering the bars
demand_color, demand_label = ax1.get_legend_handles_labels()
adoption_color, adoption_label = ax2.get_legend_handles_labels()
_ = ax1.legend(demand_color + adoption_color, demand_label + adoption_label,
loc="upper left", bbox_to_anchor=(-0.08, 1.18), bbox_transform=ax1.transAxes,
frameon=True, ncol=1, shadow=True, borderpad=0.5, fontsize=10)
autolabel(demand_bars, ax1, ".1f", "")
autolabel(adoption_bars, ax2, ".1f", "")
plt.tight_layout()
plt.show()
AI adoption rates are fairly similar across all nine countries, clustering around 50. Skill demand growth varies somewhat between countries, but with Australia at top of the list and USA at the bottom, the difference is marginal at 8%. This suggests that nations with robust manufacturing and technology industries may be putting greater emphasis on upskilling their workforce as they adopt AI, so they are not left behind.
The nested pie chart allows us to examine data at the job-role level. The outer ring illustrates each role’s portion of the average AI adoption rate, while the inner ring displays each role’s share of average skill demand growth. Both rings follow the same order, allowing for an easy comparison between roles that appear in the same positions across the rings.
# Prepare data for the nested pie chart
# Outer ring: average AI adoption level per job role
# Inner ring: average skill demand growth % per job role
# Both sorted alphabetically so matching job roles occupy the same angular position
pie_outer = (
df.groupby('job_role')['ai_adoption_level']
.mean()
.reset_index()
)
pie_outer.columns = ['job_role', 'avg_ai_adoption']
pie_inner = (
df.groupby('job_role')['skill_demand_growth_percent']
.mean()
.reset_index()
)
pie_inner.columns = ['job_role', 'avg_demand_growth']
pie_outer = pie_outer.sort_values('job_role').reset_index(drop=True)
pie_inner = pie_inner.sort_values('job_role').reset_index(drop=True)
# Set up color reference numbers for the tab20c colormap (20 colors total)
# Outer gets every even position (darker shades), inner gets every odd position (lighter shades)
number_outside_colors = len(pie_outer['job_role'].unique())
outside_color_ref_number = np.arange(number_outside_colors) * 2
number_inside_colors = len(pie_inner['job_role'].unique())
all_color_ref_number = np.arange(number_outside_colors + number_inside_colors)
inside_color_ref_number = [each for each in all_color_ref_number
if each not in outside_color_ref_number]
fig = plt.figure(figsize=(14, 14))
ax = fig.add_subplot(1, 1, 1)
colormap = plt.get_cmap("tab20c")
outer_colors = colormap(outside_color_ref_number)
inner_colors = colormap(inside_color_ref_number)
# Outer ring: AI adoption level — labels placed just outside the ring
_ = ax.pie(
pie_outer['avg_ai_adoption'],
labels=pie_outer['job_role'],
colors=outer_colors,
radius=1.0,
wedgeprops=dict(edgecolor='white', width=0.4),
startangle=90,
pctdistance=0.82,
labeldistance=1.08,
autopct=lambda p: '{:.1f}%'.format(p),
textprops={'fontsize': 12}
)
# Inner ring: skill demand growth — percentages shown inside each wedge via autopct
_ = ax.pie(
pie_inner['avg_demand_growth'],
colors=inner_colors,
radius=0.6,
wedgeprops=dict(edgecolor='white', width=0.4),
startangle=90,
pctdistance=0.72,
autopct=lambda p: '{:.1f}%'.format(p),
textprops={'fontsize': 10}
)
# White center circle creates the clean nested donut appearance
center_hole = plt.Circle((0, 0), 0.2, fc='white')
_ = ax.add_artist(center_hole)
_ = ax.set_title(
'AI Adoption Level (Outer) & Skill Demand Growth % (Inner)\nby Job Role',
fontsize=18, pad=20
)
ax.yaxis.set_visible(False)
plt.tight_layout()
plt.show()
There is a strong similarity between the two rings for all ten job roles. Each section represents approximately 10% of the totals in both rings. This even distribution indicates that no particular role stands out as the main driver of AI adoption or skill demand. Instead, AI adoption and increased skill requirements are affecting all parts of the workforce fairly evenly, rather than just impacting a few sectors more than others.
The waterfall chart shows the variance between the US average salary and the world average salary for each job role, using 2025 data which was the most recent full year of data available. Green bars mean the US pays more than the global average for that role; red bars mean the US pays less. The “Total” bar at the right shows the net overall deviation across all roles.
# Data preparation: deviation = US avg salary minus world avg salary per job role
# Uses 2025 as the most recent full year of data
# Positive deviation = US pays more than world avg; Negative = US pays less
selected_year = 2025
df_recent = df[df['year'] == selected_year]
# Compute world average and US-only average salary per job role
world_avg = df_recent.groupby('job_role')['salary_after_usd'].mean().reset_index(name='world_avg')
us_avg = (
df_recent[df_recent['country'] == 'USA']
.groupby('job_role')['salary_after_usd']
.mean()
.reset_index(name='us_avg')
)
wf_df = world_avg.merge(us_avg, on='job_role')
wf_df['deviation'] = wf_df['us_avg'] - wf_df['world_avg']
# Sort alphabetically so job roles are easy to find on the x-axis
wf_df = wf_df.sort_values('job_role').reset_index(drop=True)
# Append a Total row showing the overall net US vs world deviation
wf_df.loc[len(wf_df)] = [
'Total',
wf_df['world_avg'].mean(),
wf_df['us_avg'].mean(),
wf_df['us_avg'].mean() - wf_df['world_avg'].mean()
]
# Set total bar color based on overall deviation direction
if wf_df.loc[len(wf_df) - 1, 'deviation'] > 0:
end_color = 'green'
elif wf_df.loc[len(wf_df) - 1, 'deviation'] < 0:
end_color = 'red'
else:
end_color = 'black'
# Build measure list: 'relative' for each job role, 'total' for the final bar
measure = ['relative'] * (len(wf_df) - 1) + ['total']
fig = go.Figure(go.Waterfall(
name='',
orientation='v',
x=wf_df['job_role'],
textposition='outside',
measure=measure,
y=wf_df['deviation'],
text=['${:,.0f}'.format(each) for each in wf_df['us_avg']],
decreasing={'marker': {'color': 'red'}},
increasing={'marker': {'color': 'green'}},
totals={'marker': {'color': end_color}},
hovertemplate='Deviation from World Avg: $%{y:,.0f}<br>US Avg Salary for %{x}: %{text}'
))
fig.update_xaxes(title_text='Job Role', title_font={'size': 18})
fig.update_yaxes(
title_text='Deviation from World Avg Salary (USD)',
title_font={'size': 18},
tickprefix='$',
tickformat=',.0f',
zeroline=True
)
fig.update_layout(
title=dict(
text=f'Deviation Between US and World Average Salary by Job Role ({selected_year})<br>'
'Green = US Pays More, Red = US Pays Less Than World Average',
font=dict(family='Arial', size=18, color='black')
),
template='simple_white',
title_x=0.5,
showlegend=False,
autosize=True,
margin=dict(l=30, r=30, t=80, b=30)
)
# Store the chart HTML in a variable so R can render it inline
waterfall_html = pio.to_html(fig, full_html=False, include_plotlyjs='cdn')
In 2025, the United States provided significantly higher compensation for Truck Driver (+$3,849) and Marketing Specialist (+$1,942) positions compared to global averages. Conversely, US salaries were considerably lower for Financial Analyst (-$2,838) and Teacher (-$2,557) roles. The net Total bar is marginally negative, signifying that when all job roles are averaged, US salaries are slightly below the global average. This finding calls into question the prevailing belief that US workers consistently receive superior compensation compared to their international peers. Additionally, the data in the waterfall chart demonstrate that AI has not had a discernible impact on US compensation for the two job roles that are most at risk for AI replacement, Truck Driver and Customer Support Representative roles, as both roles have a positive deviation in compensation.
This study on AI-driven job replacement from 2020 to 2026 highlights four major insights:
Automation risk is fundamentally structural. Truck Drivers and Customer Support Representatives have maintained the highest risk of automation and AI substitution throughout this period, indicating these risks are tied directly to the nature of the jobs rather than short-term economic changes; however, compensation in the US has not decreased when compared to other countries.
AI is being adopted across all regions and industries. The level of AI integration is consistently similar in every country and job type examined, meaning no location or profession escapes uniform pressure from AI advancement.
Workforce upskilling varies by nation. Countries like Australia & demonstrate somewhat higher growth rates in skill requirements, but the rates are consistent across modern industrialized countries. This suggests more active investment in preparing workers to meet the challenges posed by AI displacement.
US salary advantages are inconsistent. Although certain positions in the United States offer pay above the global average, other job roles such as Financial Analysts and Teachers, are compensated less.