ggplot2で始めるデータ可視化 - 美しいグラフを作る実践ガイド
データ分析において、「可視化」は最も重要なスキルの一つです。数値の羅列では見えなかったパターンや傾向が、グラフにすることで一目で分かるようになります。
この記事では、R言語の代表的な可視化ライブラリ「ggplot2」の使い方を、人事データを例に実践的に解説します。ExcelやPythonのMatplotlibとの違い、美しいグラフを作るコツ、実務で使える応用例まで、私が実際に業務で使っている内容をお伝えします。
ggplot2とは
「Grammar of Graphics」の思想
ggplot2は「グラフィックスの文法」という概念に基づいています。グラフを以下の要素の組み合わせとして捉えます:
- Data(データ):可視化する元データ
- Aesthetics(美的要素):x軸、y軸、色、サイズなど
- Geometries(幾何学的要素):点、線、棒など
- Facets(分割):グラフを複数に分割
- Statistics(統計変換):平均、回帰線など
- Coordinates(座標系):直交座標、極座標など
- Theme(テーマ):見た目の調整
ExcelやPythonとの違い
| 項目 | Excel | Matplotlib(Python) | ggplot2(R) |
|---|---|---|---|
| 学習コスト | 低い | 中〜高 | 中 |
| 美しさ | ★★☆☆☆ | ★★★☆☆ | ★★★★★ |
| 柔軟性 | ★★☆☆☆ | ★★★★★ | ★★★★★ |
| 再現性 | ★★☆☆☆ | ★★★★★ | ★★★★★ |
| 統計機能 | ★★★☆☆ | ★★★☆☆ | ★★★★★ |
私がggplot2を選ぶ理由:
- 少ないコードで美しいグラフが作れる
- 一度コードを書けば、データが変わっても再利用可能
- レポート自動化(RMarkdown)との相性が抜群
- 統計処理との親和性が高い
環境構築
RとRStudioのインストール
まず、以下をインストールします:
必要なパッケージ
RStudioを起動して、以下を実行:
# Tidyverseをインストール(ggplot2も含まれる)
install.packages("tidyverse")
# 読み込み
library(tidyverse)
Tidyverseには、ggplot2の他にdplyr(データ操作)、readr(データ読み込み)なども含まれており、データ分析に必要なツールが一通り揃っています。
基本的なグラフの作り方
サンプルデータの準備
人事データを例に、実践的なグラフを作っていきます:
# サンプルデータ作成
hr_data <- tibble(
employee_id = 1:100,
department = rep(c("営業", "開発", "人事", "経理"), each = 25),
age = sample(23:60, 100, replace = TRUE),
salary = rnorm(100, mean = 5000000, sd = 1000000),
experience_years = sample(1:35, 100, replace = TRUE),
performance = sample(c("S", "A", "B", "C"), 100,
replace = TRUE,
prob = c(0.1, 0.3, 0.4, 0.2))
)
# データの確認
head(hr_data)
1. 棒グラフ(Bar Chart)
部署別の人数を可視化します:
ggplot(hr_data, aes(x = department)) +
geom_bar(fill = "#2563eb") +
labs(
title = "部署別従業員数",
x = "部署",
y = "人数"
) +
theme_minimal()
解説:
ggplot(data, aes(...)):データと軸の指定geom_bar():棒グラフを描画labs():タイトルと軸ラベルtheme_minimal():シンプルなテーマ適用
2. ヒストグラム(Histogram)
年齢の分布を可視化します:
ggplot(hr_data, aes(x = age)) +
geom_histogram(binwidth = 5, fill = "#2563eb", color = "white") +
labs(
title = "従業員の年齢分布",
x = "年齢",
y = "人数"
) +
theme_minimal()
3. 箱ひげ図(Box Plot)
部署別の年収の分布を比較します:
ggplot(hr_data, aes(x = department, y = salary, fill = department)) +
geom_boxplot() +
scale_y_continuous(labels = scales::comma) +
labs(
title = "部署別年収分布",
x = "部署",
y = "年収(円)"
) +
theme_minimal() +
theme(legend.position = "none")
箱ひげ図の見方:
- 箱の中央の線:中央値
- 箱の下端:第1四分位数(25%点)
- 箱の上端:第3四分位数(75%点)
- ひげ:最小値・最大値(外れ値を除く)
- 点:外れ値
4. 散布図(Scatter Plot)
経験年数と年収の関係を可視化します:
ggplot(hr_data, aes(x = experience_years, y = salary)) +
geom_point(color = "#2563eb", alpha = 0.6, size = 3) +
geom_smooth(method = "lm", color = "#dc2626", se = TRUE) +
scale_y_continuous(labels = scales::comma) +
labs(
title = "経験年数と年収の関係",
x = "経験年数",
y = "年収(円)"
) +
theme_minimal()
追加要素:
geom_smooth(method = "lm"):線形回帰線を追加alpha = 0.6:透明度(重なりが見やすくなる)se = TRUE:信頼区間を表示
応用テクニック
1. 色分けによる多変量表示
部署別に色分けした散布図:
ggplot(hr_data, aes(x = experience_years, y = salary, color = department)) +
geom_point(alpha = 0.7, size = 3) +
geom_smooth(method = "lm", se = FALSE) +
scale_y_continuous(labels = scales::comma) +
scale_color_manual(values = c(
"営業" = "#2563eb",
"開発" = "#dc2626",
"人事" = "#16a34a",
"経理" = "#9333ea"
)) +
labs(
title = "部署別:経験年数と年収の関係",
x = "経験年数",
y = "年収(円)",
color = "部署"
) +
theme_minimal()
2. Facetによるグラフ分割
部署ごとに別々のグラフを作成:
ggplot(hr_data, aes(x = experience_years, y = salary)) +
geom_point(color = "#2563eb", alpha = 0.6) +
geom_smooth(method = "lm", color = "#dc2626") +
scale_y_continuous(labels = scales::comma) +
facet_wrap(~department, ncol = 2) +
labs(
title = "部署別:経験年数と年収の関係",
x = "経験年数",
y = "年収(円)"
) +
theme_minimal()
3. グループ化棒グラフ
部署別・評価別の人数を比較:
# データ集計
performance_summary <- hr_data %>%
count(department, performance)
# グラフ作成
ggplot(performance_summary, aes(x = department, y = n, fill = performance)) +
geom_bar(stat = "identity", position = "dodge") +
scale_fill_manual(values = c(
"S" = "#16a34a",
"A" = "#2563eb",
"B" = "#f59e0b",
"C" = "#dc2626"
)) +
labs(
title = "部署別・評価別 従業員数",
x = "部署",
y = "人数",
fill = "評価"
) +
theme_minimal()
4. 積み上げ棒グラフ
割合を表示する場合は積み上げが便利:
ggplot(performance_summary, aes(x = department, y = n, fill = performance)) +
geom_bar(stat = "identity", position = "fill") +
scale_y_continuous(labels = scales::percent) +
scale_fill_manual(values = c(
"S" = "#16a34a",
"A" = "#2563eb",
"B" = "#f59e0b",
"C" = "#dc2626"
)) +
labs(
title = "部署別 評価分布(割合)",
x = "部署",
y = "割合",
fill = "評価"
) +
theme_minimal()
実務で使える実践例
例1:離職率の推移(折れ線グラフ)
# サンプルデータ
turnover_data <- tibble(
year = 2019:2024,
turnover_rate = c(8.5, 9.2, 7.8, 6.5, 5.9, 5.2)
)
ggplot(turnover_data, aes(x = year, y = turnover_rate)) +
geom_line(color = "#2563eb", size = 1.2) +
geom_point(color = "#2563eb", size = 3) +
geom_hline(yintercept = 7, linetype = "dashed", color = "#dc2626") +
annotate("text", x = 2024, y = 7.3, label = "業界平均", color = "#dc2626") +
scale_x_continuous(breaks = 2019:2024) +
scale_y_continuous(labels = function(x) paste0(x, "%")) +
labs(
title = "離職率の推移",
subtitle = "人事施策の効果により年々改善",
x = "年",
y = "離職率"
) +
theme_minimal()
例2:ヒートマップ(部署×評価)
# データ準備
heatmap_data <- hr_data %>%
count(department, performance) %>%
group_by(department) %>%
mutate(percentage = n / sum(n) * 100)
# ヒートマップ
ggplot(heatmap_data, aes(x = performance, y = department, fill = percentage)) +
geom_tile(color = "white") +
geom_text(aes(label = sprintf("%.1f%%", percentage)), color = "white") +
scale_fill_gradient(low = "#dbeafe", high = "#1e40af") +
labs(
title = "部署別 評価分布(ヒートマップ)",
x = "評価",
y = "部署",
fill = "割合(%)"
) +
theme_minimal()
例3:バイオリンプロット(分布の詳細表示)
ggplot(hr_data, aes(x = department, y = salary, fill = department)) +
geom_violin(alpha = 0.7) +
geom_boxplot(width = 0.2, fill = "white", alpha = 0.8) +
scale_y_continuous(labels = scales::comma) +
labs(
title = "部署別年収分布(バイオリンプロット)",
x = "部署",
y = "年収(円)"
) +
theme_minimal() +
theme(legend.position = "none")
バイオリンプロットは箱ひげ図の進化版で、分布の形状(二峰性、偏りなど)が視覚的に分かります。
美しいグラフを作るコツ
1. カラーパレットの選択
業務で使いやすいカラーパレット:
# ビジネス向け(青系)
business_colors <- c("#1e3a8a", "#2563eb", "#60a5fa", "#93c5fd")
# 信号色(良い→悪い)
signal_colors <- c("#16a34a", "#f59e0b", "#dc2626")
# カラーブラインドに配慮
colorblind_safe <- c("#0173b2", "#de8f05", "#029e73", "#cc78bc")
2. フォントとサイズの調整
ggplot(hr_data, aes(x = department, y = salary)) +
geom_boxplot(fill = "#2563eb") +
labs(title = "部署別年収分布") +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(size = 18, face = "bold"),
axis.title = element_text(size = 14),
axis.text = element_text(size = 12)
)
3. 軸の範囲調整
# 年収のグラフは0から始めると誤解を招く
ggplot(hr_data, aes(x = department, y = salary)) +
geom_boxplot() +
coord_cartesian(ylim = c(3000000, 7000000)) +
scale_y_continuous(labels = scales::comma)
4. 注釈の追加
ggplot(hr_data, aes(x = experience_years, y = salary)) +
geom_point(alpha = 0.5) +
geom_smooth(method = "lm") +
annotate("text", x = 25, y = 7000000,
label = "経験年数が\n増えるほど年収UP",
color = "#dc2626", size = 4) +
annotate("curve", x = 22, y = 6800000, xend = 18, yend = 6200000,
arrow = arrow(length = unit(0.3, "cm")),
color = "#dc2626")
グラフの保存と出力
ファイルとして保存
# 最後に作成したグラフを保存
ggsave("salary_analysis.png", width = 10, height = 6, dpi = 300)
# 特定のグラフを保存
my_plot <- ggplot(hr_data, aes(x = department, y = salary)) +
geom_boxplot()
ggsave("my_plot.png", plot = my_plot, width = 8, height = 6)
RMarkdownで自動レポート
私が月次レポートで使っているRMarkdownの例:
---
title: "人事データ月次レポート"
author: "人事部"
date: "`r Sys.Date()`"
output: html_document
---
```{r setup, include=FALSE}
library(tidyverse)
hr_data <- read_csv("hr_data.csv")
```
## 部署別年収分布
```{r, echo=FALSE, fig.width=10, fig.height=6}
ggplot(hr_data, aes(x = department, y = salary, fill = department)) +
geom_boxplot() +
theme_minimal()
```
このレポートは `r nrow(hr_data)` 名のデータに基づいています。
これをKnitすると、自動でグラフ入りのHTMLレポートが生成されます。データが更新されても、コードを実行するだけで最新のレポートができます。
まとめ
ggplot2でできること:
- 少ないコードで美しいグラフが作れる
- 再現性が高い(コード保存で同じグラフを何度でも作成)
- 柔軟性が高い(細かいカスタマイズが可能)
- 統計処理と統合(回帰線、信頼区間など自動計算)
- レポート自動化(RMarkdownと組み合わせ)
データ可視化の学習ロードマップ:
- 基本グラフ:棒グラフ、ヒストグラム、散布図(1週間)
- 色と軸:カラーパレット、スケール調整(1週間)
- 応用グラフ:Facet、ヒートマップ、バイオリン(2週間)
- 自動化:RMarkdownでレポート生成(1週間)
私自身、ggplot2を使い始めて業務効率が劇的に上がりました。Excelで1時間かかっていたグラフ作成が、コード実行だけで5秒に短縮されています。データ分析を始めたい方に、ぜひおすすめしたいツールです。