R语言可视化案例教程从入门到精通带你掌握ggplot2基础语法与高级技巧通过实战案例学会绘制散点图柱状图热力图等常见图表解决数据可视化中的实际问题

引言:为什么选择ggplot2进行数据可视化
在数据科学领域,数据可视化是探索数据和传达分析结果的关键环节。R语言的ggplot2包基于
图形语法(Grammar of Graphics)
理论,提供了一套系统化、可扩展的可视化框架。与基础绘图系统相比,ggplot2具有以下优势:
声明式语法
:通过叠加图层(Layer)的方式构建图形,逻辑清晰
高度一致性
:所有几何对象(geom)使用相同的映射规则
主题系统
:可精细控制图形的非数据元素(如字体、背景、图例位置)
扩展生态
:超过100个扩展包支持特殊图表类型
本文将从基础语法讲起,通过实战案例带你掌握散点图、柱状图、热力图等常见图表的绘制方法,并解决数据可视化中的实际问题。
第一部分:ggplot2基础语法
1.1 图形语法核心概念
ggplot2的图形构建基于以下核心组件:
数据(Data)
:必须是data.frame格式
美学映射(Aesthetics)
:将数据变量映射到图形属性(颜色、形状、大小等)
几何对象(Geometries)
:决定图形的类型(点、线、条等)
标度(Scales)
:控制美学映射的具体表现(如颜色方案)
坐标系(Coordinates)
:定义坐标轴(笛卡尔坐标、极坐标等)
分面(Facets)
:按变量拆分多个子图
主题(Theme)
:控制非数据元素的视觉样式
1.2 第一个ggplot2图形
# 安装和加载包
install.packages(“ggplot2”)
library(ggplot2)

# 使用内置数据集mtcars
data(mtcars)

# 创建基础图形:将wt(车重)映射到x轴,mpg(油耗)映射到y轴
p <- ggplot(data = mtcars, aes(x = wt, y = mpg)) # 添加散点图层 p + geom_point() # 完整代码示例(可直接运行) library(ggplot2) ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point(color = "steelblue", size = 3, alpha = 0.7) + labs(title = "汽车重量与油耗关系", x = "重量(千磅)", y = "每加仑里程") + theme_minimal() 代码解析 : ggplot() 初始化图形,指定数据和基础映射 geom_point() 添加散点图层 labs() 设置标签 theme_minimal() 应用简洁主题 1.3 美学映射详解 美学映射是ggplot2的核心,它将数据变量映射到视觉属性: # 颜色映射(按cyl气缸数分组) ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) + geom_point(size = 4) + scale_color_brewer(palette = "Set1", name = "气缸数") + labs(title = "按气缸数分组的汽车重量与油耗") # 形状映射(按am变速箱类型) ggplot(mtcars, aes(x = wt, y = mpg, shape = factor(am))) + geom_point(size = 4, color = "darkred") + scale_shape_manual(values = c(16, 17), labels = c("自动", "手动")) + labs(title = "按变速箱类型分组的汽车重量与油耗") # 多重映射(同时使用颜色和大小) ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl), size = hp)) + geom_point(alpha = 0.8) + scale_size_continuous(range = c(2, 10)) + labs(title = "汽车重量、油耗、气缸数和马力的关系") 关键点 : 在 aes() 内部的映射是 动态 的,会随数据变化 在 geom_*() 外部指定的属性是 静态 的,对所有数据点统一 因子变量会自动映射为离散颜色/形状 连续变量会自动映射为渐变颜色/大小 1.4 常用几何对象 # 1. 折线图(时间序列) economics <- ggplot2::economics ggplot(economics, aes(x = date, y = unemploy)) + geom_line(color = "steelblue", size = 1) + labs(title = "美国失业人数时间序列", x = "年份", y = "失业人数(千人)") # 2. 直方图(单变量分布) ggplot(mtcars, aes(x = mpg)) + geom_histogram(binwidth = 3, fill = "skyblue", color = "black") + labs(title = "汽车油耗分布直方图", x = "每加仑里程", y = "频数") # 3. 箱线图(分组比较) ggplot(mtcars, aes(x = factor(cyl), y = mpg, fill = factor(cyl))) + geom_boxplot() + labs(title = "不同气缸数的油耗箱线图", x = "气缸数", y = "每加仑里程") # 4. 密度图(分布曲线) ggplot(mtcars, aes(x = mpg, fill = factor(cyl))) + geom_density(alpha = 0.6) + labs(title = "不同气缸数的油耗密度图", x = "每加仑里程", y = "密度") 第二部分:散点图实战与高级技巧 2.1 基础散点图与修饰 散点图是探索两个连续变量关系的首选图表: # 使用iris数据集 data(iris) # 基础散点图 p <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) + geom_point(size = 3, alpha = 0.8) + labs(title = "鸢尾花萼片长度与宽度关系", subtitle = "按物种分类", x = "萼片长度(cm)", y = "萼片宽度(cm)", color = "物种") # 添加回归线(分组) p + geom_smooth(method = "lm", se = FALSE, linetype = "dashed") # 添加平滑曲线(局部多项式回归) p + geom_smooth(method = "loess", se = TRUE, alpha = 0.2) 2.2 散点图标注与注释 # 计算各组的中心点 library(dplyr) centroids <- iris %>%
group_by(Species) %>%
summarize(avg_length = mean(Sepal.Length), avg_width = mean(Sepal.Width))

# 绘制带标注的散点图
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
geom_point(size = 3, alpha = 0.7) +
geom_point(data = centroids, aes(x = avg_length, y = avg_width),
size = 5, shape = 8, stroke = 2) +
geom_text(data = centroids, aes(x = avg_length, y = avg_width, label = Species),
vjust = -1, fontface = “bold”, size = 4) +
labs(title = “鸢尾花数据带中心点标注”) +
theme(legend.position = “none”)
2.3 散点图矩阵(Pairs Plot)
# 使用GGally包创建散点图矩阵
install.packages(“GGally”)
library(GGally)

# 基础矩阵
ggpairs(iris, columns = 1:4, aes(color = Species, alpha = 0.5))

# 自定义矩阵(仅显示下三角)
ggpairs(iris, columns = 1:4,
upper = list(continuous = “cor”),
lower = list(continuous = “points”),
diag = list(continuous = “densityDiag”),
aes(color = Species))
2.4 散点图动画(使用gganimate)
# 安装动画包
install.packages(c(“gganimate”, “gapminder”))
library(gganimate)
library(gapminder)

# 创建动态散点图
p <- ggplot(gapminder, aes(x = gdpPercap, y = lifeExp, size = pop, color = country)) + geom_point(alpha = 0.7, show.legend = FALSE) + scale_x_log10() + facet_wrap(~continent) + labs(title = '年份: {frame_time}', x = '人均GDP', y = '预期寿命') + transition_time(year) + ease_aes('linear') # 渲染动画(需要GIF支持) animate(p, renderer = gifski_renderer(), width = 800, height =600, fps = 20) 第三部分:柱状图与条形图 3.1 基础柱状图 # 使用dplyr准备汇总数据 library(dplyr) mtcars_summary <- mtcars %>%
group_by(cyl) %>%
summarize(avg_mpg = mean(mpg), count = n())

# 基础柱状图
ggplot(mtcars_summary, aes(x = factor(cyl), y = avg_mpg)) +
geom_col(fill = “steelblue”, width = 0.7) +
labs(title = “不同气缸数的平均油耗”, x = “气缸数”, y = “平均MPG”)

# 带数值标签
ggplot(mtcars_summary, aes(x = factor(cyl), y = avg_mpg)) +
geom_col(fill = “steelblue”, width = 0.7) +
geom_text(aes(label = round(avg_mpg, 1)), vjust = -0.5, size = 4) +
labs(title = “不同气缸数的平均油耗(带数值)”)
3.2 堆叠柱状图与分组柱状图
# 准备数据:按cyl和gear分组
mtcars_complex <- mtcars %>%
group_by(cyl, gear) %>%
summarize(count = n()) %>%
ungroup()

# 堆叠柱状图
ggplot(mtcars_complex, aes(x = factor(cyl), y = count, fill = factor(gear))) +
geom_col() +
scale_fill_brewer(palette = “Set2”, name = “档位”) +
labs(title = “不同气缸数的档位分布(堆叠)”, x = “气缸数”, y = “数量”)

# 分组柱状图
ggplot(mtcars_complex, aes(x = factor(cyl), y = count, fill = factor(gear))) +
geom_col(position = “dodge”) +
scale_fill_brewer(palette = “Set2”, name = “档位”) +
labs(title = “不同气缸数的档位分布(分组)”, x = “气缸数”, y = “数量”)
3.3 水平柱状图与重排序
# 对数据按平均MPG排序
mtcars_summary <- mtcars_summary %>%
arrange(avg_mpg) %>%
mutate(cyl_ordered = factor(cyl, levels = cyl))

# 水平柱状图(按MPG升序)
ggplot(mtcars_summary, aes(x = cyl_ordered, y = avg_mpg)) +
geom_col(fill = “darkgreen”, width = 0.8) +
coord_flip() + # 翻转坐标轴
labs(title = “不同气缸数的平均油耗(水平)”, x = “气缸数”, y = “平均MPG”) +
geom_text(aes(label = round(avg_mpg, 1)), hjust = -0.2, size = 4)
3.4 条形图(宽度表示比例)
# 使用ggplot2内置的diamonds数据集
library(ggplot2)
diamonds_sample <- diamonds %>% sample_n(1000)

# 条形图(cut为有序因子)
ggplot(diamonds_sample, aes(x = cut)) +
geom_bar(fill = “orange”, width = 0.6) +
labs(title = “钻石切工分布条形图”, x = “切工等级”, y = “数量”) +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
3.5 森林图(临床研究常用)
# 模拟临床研究数据
clinical_data <- data.frame( treatment = c("药物A", "药物B", "药物C", "药物D"), hr = c(0.72, 0.85, 0.68, 0.92), ci_lower = c(0.58, 0.72, 0.55, 0.78), ci_upper = c(0.89, 1.00, 0.84, 1.08) ) # 森林图 ggplot(clinical_data, aes(x = treatment, y = hr, ymin = ci_lower, ymax = ci_upper)) + geom_pointrange(shape = 15, size = 1, color = "steelblue") + geom_hline(yintercept = 1, linetype = "dashed", color = "red") + coord_flip() + scale_y_log10() + labs(title = "治疗效果森林图", subtitle = "HR < 1 表示有效", x = "治疗方案", y = "风险比(HR)及其95%置信区间") + theme_minimal() 第四部分:热力图与矩阵可视化 4.1 基础热力图 # 使用内置的volcano数据集(地形高度矩阵) data(volcano) # 将矩阵转换为长格式数据框 library(reshape2) volcano_df <- melt(volcano) colnames(volcano_df) <- c("x", "y", "height") # 基础热力图 ggplot(volcano_df, aes(x = x, y = y, fill = height)) + geom_raster() + # 使用矩形像素 scale_fill_gradientn(colors = c("green", "yellow", "red")) + labs(title = "火山地形热力图", x = "X坐标", y = "Y坐标", fill = "高度") 4.2 相关性矩阵热力图 # 计算相关性矩阵 cor_matrix <- cor(mtcars[, 1:7]) # 转换为长格式 cor_df <- melt(cor_matrix) colnames(cor_matrix) <- c("Var1", "Var2", "Correlation") # 相关性热力图 ggplot(cor_df, aes(x = Var1, y = Var2, fill = Correlation)) + geom_tile(color = "white", size = 0.5) + scale_fill_gradient2(low = "blue", mid = "white", high = "red", midpoint = 0) + labs(title = "mtcars变量相关性矩阵", x = "", y = "") + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust = 1)) + coord_fixed() # 保持x和y比例相同 4.3 聚类热力图(ComplexHeatmap) # 使用ComplexHeatmap包(更专业的热力图) install.packages("ComplexHeatmap") library(ComplexHeatmap) library(circlize) # 准备数据:鸢尾花数据标准化 iris_matrix <- as.matrix(iris[, 1:4]) rownames(iris_matrix) <- paste("Sample", 1:nrow(iris_matrix)) # 创建热力图 Heatmap(iris_matrix, name = "表达量", col = colorRamp2(c(4, 6, 8), c("blue", "white", "red")), show_row_names = FALSE, cluster_rows = TRUE, cluster_columns = TRUE, row_title = "样本", column_title = "花萼/花瓣特征") 4.4 时间序列热力图(日历热力图) # 创建日历热力图数据 library(lubridate) dates <- seq(as.Date("2023-01-01"), as.Date("2023-12-31"), by = "day") values <- rnorm(length(dates), mean = 100, sd = 15) calendar_df <- data.frame( date = dates, value = values, week = week(dates), wday = wday(dates, label = TRUE), month = month(dates, label = TRUE) ) # 日历热力图 ggplot(calendar_df, aes(x = week, y = wday, fill = value)) + geom_tile(color = "white", size = 0.5) + facet_wrap(~month, ncol = 3) + scale_fill_gradientn(colors = c("lightblue", "steelblue", "darkblue")) + labs(title = "2023年数值日历热力图", x = "周数", y = "星期", fill = "数值") + theme(strip.text = element_text(face = "bold", size = 12)) 第五部分:高级技巧与自定义 5.1 自定义主题(Theme) # 创建自定义主题 my_theme <- function() { theme( # 背景 panel.background = element_rect(fill = "white"), panel.grid.major = element_line(color = "gray90", linetype = "dashed"), panel.grid.minor = element_blank(), # 边框 panel.border = element_rect(color = "black", fill = NA, size = 1), # 标题和文本 plot.title = element_text(size = 18, face = "bold", hjust = 0.5), plot.subtitle = element_text(size = 12, face = "italic", hjust = 0.5), axis.title = element_text(size = 14, face = "bold"), axis.text = element_text(size = 12), # 图例 legend.position = "bottom", legend.title = element_text(face = "bold"), legend.key = element_rect(fill = "white", color = "black"), # 分面标签 strip.background = element_rect(fill = "lightblue", color = "black"), strip.text = element_text(face = "bold", size = 12) ) } # 应用自定义主题 ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) + geom_point(size = 4) + labs(title = "自定义主题示例", subtitle = "使用my_theme()") + my_theme() 5.2 坐标系变换 # 极坐标(饼图/雷达图) pie_data <- mtcars_summary pie_data$fraction <- pie_data$avg_mpg / sum(pie_data$avg_mpg) pie_data$ymax <- cumsum(pie_data$fraction) pie_data$ymin <- c(0, head(pie_data$ymax, n = -1)) # 饼图 ggplot(pie_data, aes(ymax = ymax, ymin = ymin, xmax = 4, xmin = 3, fill = factor(cyl))) + geom_rect() + coord_polar(theta = "y") + xlim(c(2, 4)) + labs(title = "平均油耗饼图", fill = "气缸数") + theme_void() # 对数坐标 ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + scale_y_log10() + labs(title = "Y轴对数坐标", y = "MPG(对数尺度)") 5.3 分面系统(Facets) # 基础分面 ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point(aes(color = factor(gear))) + facet_wrap(~factor(cyl), labeller = labeller(cyl = c("4" = "4缸", "6" = "6缸", "8" = "8缸"))) + labs(title = "按气缸数分面", x = "重量", y = "MPG") + theme(strip.text = element_text(size = 14, face = "bold")) # 网格分面(两个变量) mtcars$am <- factor(mtcars$am, labels = c("自动", "手动")) mtcars$gear <- factor(mtcars$gear) ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + facet_grid(am ~ gear, labeller = label_both) + labs(title = "按变速箱类型和档位数网格分面") 5.4 组合图形(双坐标轴) # 创建双坐标轴数据 dual_data <- data.frame( month = 1:12, sales = rnorm(12, 500, 100), profit = rnorm(12, 50, 10) ) # 双坐标轴图形(注意:需谨慎使用) ggplot(dual_data, aes(x = month)) + geom_col(aes(y = sales), fill = "steelblue", alpha = 0.7) + geom_line(aes(y = profit * 10), color = "red", size = 1.5, group = 1) + scale_y_continuous( name = "销售额", sec.axis = sec_axis(~./10, name = "利润") ) + labs(title = "销售额与利润(双坐标轴)", x = "月份") + theme( axis.title.y.right = element_text(color = "red"), axis.text.y.right = element_text(color = "R") ) 5.5 交互式图形(Plotly) # 安装和加载 install.packages("plotly") library(plotly) # 将ggplot2转换为交互式 p <- ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl), size = hp)) + geom_point(alpha = 0.7) + labs(title = "交互式散点图") ggplotly(p, tooltip = c("x", "y", "color", "size")) 第六部分:实战案例解决实际问题 6.1 案例1:处理大数据量散点图(过绘制问题) 问题 :当数据点超过10万时,散点图会重叠严重,无法识别模式。 解决方案 : # 创建大数据集(10万行) set.seed(123) big_data <- data.frame( x = rnorm(100000), y = rnorm(100000), group = sample(1:5, 100000, replace = TRUE) ) # 方法1:透明度调整 p1 <- ggplot(big_data, aes(x = x, y = y)) + geom_point(alpha = 0.1, size = 0.5) + labs(title = "方法1:降低透明度") # 方法2:分箱统计(hexbin) install.packages("hexbin") library(hexbin) p2 <- ggplot(big_data, aes(x = x, y = y)) + geom_hex(bins = 50) + scale_fill_viridis_c() + labs(title = "方法2:六边形分箱") # 方法3:核密度估计 p3 <- ggplot(big_data, aes(x = x, y = y)) + geom_density_2d() + labs(title = "方法3:二维密度") # 方法4:数据抽样 p4 <- big_data %>%
sample_n(5000) %>%
ggplot(aes(x = x, y = y)) +
geom_point(alpha = 0.5) +
labs(title = “方法4:随机抽样”)

# 组合展示
library(patchwork)
(p1 | p2) / (p3 | p4)
6.2 案例2:时间序列异常检测可视化
问题
:在时间序列中快速识别异常值。
解决方案
:
# 创建时间序列数据
set.seed(456)
time_data <- data.frame( date = seq(as.Date("2023-01-01"), as.Date("2023-12-31"), by = "day"), value = 100 + 10 * sin(1:365 / 30) + rnorm(365, 0, 5) ) # 添加异常点 time_data$value[c(50, 150, 250)] <- c(150, 60, 180) # 计算移动平均和标准差 library(zoo) time_data$ma <- rollmean(time_data$value, k = 7, fill = NA, align = "right") time_data$sd <- rollapply(time_data$value, width = 7, FUN = sd, fill = NA, align = "right") # 识别异常(超过2倍标准差) time_data$anomaly <- abs(time_data$value - time_data$ma) > 2 * time_data$sd

# 可视化
ggplot(time_data, aes(x = date, y = value)) +
geom_line(color = “gray70”, size = 0.8) +
geom_line(aes(y = ma), color = “blue”, linetype = “dashed”, size = 1) +
geom_line(aes(y = ma + 2*sd), color = “red”, linetype = “dotted”, size = 0.5) +
geom_line(aes(y = ma – 2*sd), color = “red”, linetype = “dotted”, size = 0.5) +
geom_point(data = subset(time_data, anomaly),
color = “red”, size = 3, shape = 18) +
geom_text(data = subset(time_data, anomaly),
aes(label = paste(“异常:”, value)), vjust = -1, color = “red”) +
labs(title = “时间序列异常检测”, x = “日期”, y = “数值”,
subtitle = “红色虚线:±2倍标准差,红色星号:异常值”) +
theme_minimal()
6.3 案例3:多变量比较(雷达图与平行坐标图)
问题
:同时比较多个变量在不同组间的差异。
解决方案
:
# 准备数据:各组在不同指标上的表现
radar_data <- data.frame( group = rep(c("A组", "B组", "C组"), each = 5), variable = rep(c("效率", "成本", "质量", "创新", "服务"), 3), value = c(80, 70, 90, 85, 75, # A组 75, 85, 70, 80, 90, # B组 90, 60, 85, 75, 80) # C组 ) # 雷达图(使用ggplot2极坐标) ggplot(radar_data, aes(x = variable, y = value, color = group, group = group)) + geom_polygon(fill = NA, size = 1.5, alpha = 0.2) + geom_point(size = 3) + coord_polar() + scale_y_continuous(limits = c(0, 100)) + labs(title = "多组别多变量雷达图", color = "组别") + theme_minimal() + theme(axis.title = element_blank(), panel.grid.major = element_line(color = "gray80")) # 平行坐标图(使用GGally) library(GGally) parallel_data <- mtcars %>%
group_by(cyl) %>%
summarize(across(c(mpg, hp, wt, qsec), mean)) %>%
mutate(cyl = factor(cyl))

ggparcoord(parallel_data, columns = 2:5, groupColumn = 1,
alphaLines = 0.7, scale = “globalminmax”) +
labs(title = “平行坐标图:多变量比较”, x = “变量”, y = “标准化值”) +
theme_minimal()
6.4 案例4:地理空间数据可视化
问题
:在地图上展示空间分布数据。
解决方案
:
# 安装地图包
install.packages(c(“maps”, “mapdata”, “ggmap”))
library(maps)
library(mapdata)
library(ggplot2)

# 中国地图(简略)
china_map <- map_data("worldHires", region = "China") # 模拟城市数据 city_data <- data.frame( city = c("北京", "上海", "广州", "深圳", "成都"), lon = c(116.4, 121.5, 113.3, 114.1, 104.1), lat = c(39.9, 31.2, 23.1, 22.5, 30.7), value = c(100, 95, 85, 90, 80) ) # 绘制地图 ggplot() + geom_polygon(data = china_map, aes(x = long, y = lat, group = group), fill = "lightyellow", color = "gray50", size = 0.3) + geom_point(data = city_data, aes(x = lon, y = lat, size = value, color = value)) + geom_text(data = city_data, aes(x = lon, y = lat, label = city), vjust = -1, size = 3, fontface = "bold") + scale_color_gradient(low = "blue", high = "red") + scale_size_continuous(range = c(3, 10)) + labs(title = "中国主要城市分布", x = "经度", y = "纬度", size = "指标值", color = "指标值") + coord_map(projection = "mercator") + theme_minimal() + theme(legend.position = "right") 6.5 案例5:仪表盘布局(多图组合) 问题 :将多个相关图表组合成一个仪表盘。 解决方案 : # 使用patchwork包进行布局 library(patchwork) # 创建多个子图 p1 <- ggplot(mtcars, aes(x = factor(cyl), y = mpg, fill = factor(cyl))) + geom_boxplot() + labs(title = "油耗分布") + theme(legend.position = "none") p2 <- ggplot(mtcars, aes(x = hp, y = mpg)) + geom_point(color = "steelblue") + labs(title = "马力 vs 油耗") p3 <- ggplot(mtcars, aes(x = factor(gear))) + geom_bar(fill = "darkgreen") + labs(title = "档位分布", x = "档位") p4 <- ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) + geom_point() + labs(title = "重量 vs 油耗") + theme(legend.position = "none") # 组合布局(2x2网格) dashboard <- (p1 + p2) / (p3 + p4) + plot_annotation( title = "汽车性能分析仪表盘", subtitle = "数据来源:mtcars数据集", caption = "生成时间:Sys.Date()", theme = theme(title = element_text(size = 16, face = "bold")) ) print(dashboard) # 保存为高分辨率图片 ggsave("dashboard.png", plot = dashboard, width = 12, height = 8, dpi = 300) 第七部分:性能优化与最佳实践 7.1 大数据量渲染优化 # 1. 使用data.table加速数据处理 install.packages("data.table") library(data.table) # 2. 预处理数据,避免在ggplot中计算 # 3. 使用ggsave优化输出 ggsave("high_res_plot.png", plot = last_plot(), width = 10, height = 6, dpi = 600, type = "cairo", # 抗锯齿 limitsize = FALSE) # 4. 使用grid.arrange避免重复渲染 library(gridExtra) grid.arrange(p1, p2, p3, p4, ncol = 2) 7.2 颜色使用最佳实践 # 色盲友好调色板 library(RColorBrewer) display.brewer.all(colorblindFriendly = TRUE) # 自定义色盲友好颜色 color_blind_friendly <- c("#0072B2", "#D55E00", "#009E73", "#CC79A7", "#F0E442") # 连续变量使用渐变 ggplot(mtcars, aes(x = wt, y = mpg, color = hp)) + geom_point(size = 4) + scale_color_gradientn(colors = c("blue", "white", "red")) + labs(title = "色盲友好渐变颜色") # 离散变量使用Set2调色板 ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) + geom_point(size = 4) + scale_color_brewer(palette = "Set2") + labs(title = "Set2调色板") 7.3 导出与分享 # 不同格式导出 # PNG(位图) ggsave("plot.png", width = 8, height = 6, dpi = 300) # PDF(矢量图,适合印刷) ggsave("plot.pdf", width = 8, height = 6, device = cairo_pdf) # SVG(矢量图,适合网页) ggsave("plot.svg", width = 8, height = 6) # 保存为R对象(可重新编辑) saveRDS(last_plot(), "my_plot.rds") loaded_plot <- readRDS("my_plot.rds") print(loaded_plot) 7.4 常见错误与调试 # 错误1:数据不是data.frame # 错误:ggplot(list(1:10, 1:10)) # 正确:ggplot(data.frame(x=1:10, y=1:10), aes(x=x, y=y)) # 错误2:美学映射位置错误 # 错误:geom_point(color = "red") # 静态颜色 # 正确:geom_point(aes(color = group)) # 动态映射 # 错误3:因子变量未转换 # 错误:ggplot(data, aes(x = numeric_group, y = value)) + geom_boxplot() # 正确:ggplot(data, aes(x = factor(numeric_group), y = value)) + geom_boxplot() # 调试技巧 # 1. 检查数据结构 str(your_data) # 2. 检查映射 ggplot(your_data, aes(x = your_x, y = your_y)) + geom_point() # 3. 逐步添加图层 p <- ggplot(your_data, aes(x = your_x, y = your_y)) p + geom_point() p + geom_point() + geom_smooth() 第八部分:扩展包生态系统 8.1 必装扩展包 # 数据准备 install.packages(c("dplyr", "tidyr", "lubridate")) # 可视化增强 install.packages(c("patchwork", "ggrepel", "ggforce", "ggpubr")) # 特定领域 install.packages(c("gganimate", "plotly", "leaflet", "sf")) # 主题扩展 install.packages(c("ggthemes", "hrbrthemes")) 8.2 扩展包实战 # ggrepel:避免标签重叠 library(ggrepel) ggplot(mtcars, aes(x = wt, y = mpg, label = rownames(mtcars))) + geom_point(color = "steelblue") + geom_text_repel(min.segment.length = 0, box.padding = 0.5) + labs(title = "ggrepel:自动调整标签位置") # ggforce:高级几何对象 library(ggforce) ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) + geom_point() + geom_mark_hull(aes(fill = factor(cyl)), alpha = 0.2, concavity = 2) + labs(title = "ggforce:凸包标记") # ggpubr:出版级图表 library(ggpubr) ggboxplot(mtcars, x = "cyl", y = "mpg", fill = "cyl") + stat_compare_means(method = "anova", label.y = 35) + labs(title = "ggpubr:带统计检验的箱线图") 总结 通过本文的系统学习,你已经掌握了ggplot2的核心语法和高级技巧。从基础的散点图、柱状图到复杂的热力图、地理空间图,再到解决大数据量、异常检测等实际问题,ggplot2都能提供优雅的解决方案。 关键要点回顾 : 图形语法 :数据 + 映射 + 几何对象 + 标度 + 坐标系 + 分面 + 主题 图层叠加 :通过 + 操作符逐步构建图形 美学映射 :在 aes() 内使用变量,外部使用常量 主题系统 :精细控制图形外观 扩展生态 :利用扩展包解决特定需求 下一步建议 : 练习真实数据集(如Kaggle数据) 阅读《R for Data Science》相关章节 参考ggplot2官方文档和cheatsheet 在实际项目中应用所学技巧 记住,优秀的数据可视化不仅是技术展示,更是数据故事的讲述。通过ggplot2,你可以将枯燥的数据转化为引人入胜的视觉叙事。