効果的なデータ可視化は、技術的な実装だけでなく、設計原則、ユーザビリティ、ストーリーテリングの組み合わせです。これまでの章で学んだ技術を統合し、プロフェッショナルレベルの可視化を作成する方法を学びます。
library(ggplot2)
library(dplyr)
library(scales)
library(patchwork)
library(ggtext)
create_visualization_system <- function() {
design_system <- list(
colors = list(
primary = "#2563eb",
secondary = "#059669",
accent = "#dc2626",
warning = "#d97706",
neutral = c("#374151", "#6b7280", "#9ca3af"),
background = "#f9fafb",
categorical = c("#2563eb", "#059669", "#dc2626", "#7c3aed", "#ea580c")
),
typography = list(
title_size = 16,
subtitle_size = 12,
body_size = 10,
caption_size = 8,
font_family = "Arial"
),
spacing = list(
base = 8,
small = 4,
medium = 12,
large = 20,
xlarge = 32
)
)
theme_professional <- function(
base_size = design_system$typography$body_size,
grid = TRUE,
border = FALSE
) {
theme_minimal(base_size = base_size, base_family = design_system$typography$font_family) +
theme(
plot.background = element_rect(fill = design_system$colors$background, color = NA),
panel.background = element_rect(fill = "white", color = NA),
panel.border = if (border) element_rect(fill = NA, color = design_system$colors$neutral[2]) else element_blank(),
plot.title = element_text(
size = design_system$typography$title_size,
face = "bold",
color = design_system$colors$neutral[1],
margin = margin(b = design_system$spacing$medium)
),
plot.subtitle = element_text(
size = design_system$typography$subtitle_size,
color = design_system$colors$neutral[2],
margin = margin(b = design_system$spacing$large)
),
plot.caption = element_text(
size = design_system$typography$caption_size,
color = design_system$colors$neutral[3],
hjust = 0,
margin = margin(t = design_system$spacing$medium)
),
axis.title = element_text(
size = design_system$typography$body_size,
color = design_system$colors$neutral[1],
face = "bold"
),
axis.text = element_text(
size = design_system$typography$body_size - 1,
color = design_system$colors$neutral[2]
),
axis.line = element_line(color = design_system$colors$neutral[3], size = 0.5),
axis.ticks = element_line(color = design_system$colors$neutral[3], size = 0.3),
panel.grid.major = if (grid) element_line(color = "#f1f5f9", size = 0.5) else element_blank(),
panel.grid.minor = element_blank(),
legend.title = element_text(
size = design_system$typography$body_size,
face = "bold",
color = design_system$colors$neutral[1]
),
legend.text = element_text(
size = design_system$typography$body_size - 1,
color = design_system$colors$neutral[2]
),
legend.position = "bottom",
legend.margin = margin(t = design_system$spacing$medium),
strip.background = element_rect(
fill = "#e2e8f0",
color = NA
),
strip.text = element_text(
size = design_system$typography$body_size,
face = "bold",
color = design_system$colors$neutral[1],
margin = margin(design_system$spacing$small)
),
plot.margin = margin(
design_system$spacing$large,
design_system$spacing$large,
design_system$spacing$large,
design_system$spacing$large
)
)
}
scale_color_professional <- function(...) {
scale_color_manual(values = design_system$colors$categorical, ...)
}
scale_fill_professional <- function(...) {
scale_fill_manual(values = design_system$colors$categorical, ...)
}
create_title_block <- function(title, subtitle = NULL, source = NULL) {
title_text <- paste0("**", title, "**")
if (!is.null(subtitle)) {
title_text <- paste0(title_text, "<br><span style='font-size:",
design_system$typography$subtitle_size, "pt; color:",
design_system$colors$neutral[2], ";'>", subtitle, "</span>")
}
caption_text <- NULL
if (!is.null(source)) {
caption_text <- paste0("出典: ", source, " | 作成日: ", format(Sys.Date(), "%Y年%m月%d日"))
}
list(title = title_text, caption = caption_text)
}
list(
design_system = design_system,
theme_professional = theme_professional,
scale_color_professional = scale_color_professional,
scale_fill_professional = scale_fill_professional,
create_title_block = create_title_block
)
}
viz_system <- create_visualization_system()
set.seed(42)
business_performance <- tibble(
quarter = rep(paste0(2022, "-Q", 1:4, " / ", 2023, "-Q", 1:4), each = 5),
department = rep(c("営業", "マーケティング", "開発", "サポート", "管理"), 8),
revenue = round(rnorm(40, 15000, 3000)),
expenses = round(rnorm(40, 12000, 2000)),
satisfaction = round(rnorm(40, 4.2, 0.5), 1)
) %>%
mutate(
profit = revenue - expenses,
profit_margin = round((profit / revenue) * 100, 1),
year = ifelse(str_detect(quarter, "2022"), "2022", "2023"),
quarter_num = as.numeric(str_extract(quarter, "Q([1-4])"))
)
print("プロフェッショナル可視化システムが構築されました")