数据准备
不手写“看起来像真的”数字。直接读取 Tessera 的 economy_countries Toy,取 2023 年 GDP 最高的 10 个经济体;标签统一换算成万亿美元。Top 10 也给每个标签留下足够空间,不为了多塞两块而牺牲可读性。
library(dplyr)
library(ggplot2)
library(treemapify)
library(biopalette)
economy <- read.csv(
"content/tessera/data/csv/economy_countries.csv",
check.names = FALSE
)
plot_data <- economy |>
filter(year == 2023, !is.na(gdp_usd), gdp_usd > 0) |>
slice_max(gdp_usd, n = 10, with_ties = FALSE) |>
mutate(
country_label = recode(
country,
"Russian Federation" = "Russia",
"Korea" = "South Korea",
.default = country
),
label = paste0(country_label, "\n", sprintf("$%.1fT", gdp_usd / 1e12))
)
# 显式固定地区顺序,保证分层版的空间组织可复现。
region_levels <- c(
"North America",
"East Asia & Pacific",
"Europe & Central Asia",
"South Asia",
"Latin America & Caribbean"
)
plot_data <- plot_data |>
mutate(region = factor(region, levels = region_levels)) |>
arrange(desc(gdp_usd))
# 每个国家固定一种颜色;命名映射不受后续排序和分组影响。
country_colors <- setNames(
get_palette("babel", type = "qualitative")[c(1, 2, 3, 4, 8, 9, 11, 12, 13, 20)],
plot_data$country_label
)
region_colors <- setNames(
get_palette("walter_white2", type = "qualitative"),
region_levels
)
PAPER <- "#F4F3EE"
INK <- "#353531"
方法 A · 扁平 treemap
这一版不建立空间层级。所有国家在同一层比较,每个国家使用不同颜色;国家名已经直接标在矩形中,因此不再重复放置图例。
#| fig: basic
#| fig-width: 8
#| fig-height: 6
ggplot(plot_data, aes(area = gdp_usd, fill = country_label, label = label)) +
geom_treemap(
colour = PAPER,
linewidth = 1.1,
alpha = 0.62,
start = "topleft"
) +
geom_treemap_text(
colour = INK,
place = "centre",
grow = FALSE,
reflow = TRUE,
size = 9,
min.size = 5.5,
padding.x = grid::unit(2.4, "mm"),
padding.y = grid::unit(2.4, "mm"),
start = "topleft"
) +
scale_fill_manual(values = country_colors, guide = "none") +
labs(
title = "The world’s largest economies",
subtitle = "Area shows 2023 GDP; each country keeps its own color",
caption = "Source: Tessera economy_countries toy · current US$"
) +
theme_void(base_size = 12) +
theme(
plot.title = element_text(
colour = INK, size = 17, face = "bold", hjust = 0,
margin = margin(b = 4)
),
plot.subtitle = element_text(
colour = INK, size = 10.5, hjust = 0,
margin = margin(b = 12)
),
plot.caption = element_text(colour = INK, size = 8.5, hjust = 1),
plot.margin = margin(16, 18, 12, 18),
plot.background = element_rect(fill = PAPER, colour = NA),
panel.background = element_rect(fill = PAPER, colour = NA)
)