5.1 简介
# 本章每一节 解决一个特定的作图问题
# 1,基本的图形类型 详见5.3
# 2,展示分布 详见5.4
# 3,应对散点图中的遮盖绘制问题 详见5.5
# 4,绘制曲面图 详见5.6
# 5,统计汇总 详见5.9
# 6,绘制地图 详见5.7
# 7,揭示数据中的不确定性和误差 详见5.8
# 8,为图形添加注解 详见5.10
# 9,绘制加权的数据 详见5.11
5.2 图层叠加的总体策略
# 在添加图层之前弄清楚它的作用是十分必要的。总体来说,图层有三种用途:
# 1,用以展示 数据本身
# 2,用以展示数据的统计 摘要
# 3,用以添加额外的 元数据
5.3 基本图形类型
# 这些几何对象均是二维的,故x和y两种图形属性都是不可或缺的。同时,它们都可以接受colour和size图形属性
# 另外,填充型几何对象(条形、瓦片和多边形)还可以接受fill图形属性。
# 点使用shape图形属性,线和路径接受linetype图形属性。
# 这些几何对象可用于展示原始数据,另行计算得到的数据摘要和元数据
# geom_area() 面积图
# geom_bar(stat= "identity") 条形图
# geom_line() 线条图
# geom_point() 散点图
# geom_polygon() 多边形,即填充后的路径图
# geom_text() 指定点处添加标签
# geom_tile() 绘制色深图,或水平图
# 示例
df <- data.frame(x = c(3,1,5),y = c(2,4,6),label = c("a","b","c"))
p <- ggplot(df,aes(x,y)) + xlab(NULL) +ylab(NULL)
p + geom_point() + labs(title = "geom_point")
p + geom_bar(stat = "identity") + labs(title = "geom_bar(stat=\"identity\")")
p + geom_line() + labs(title = "geom_line")
p + geom_area() + labs(title = "geom_area")
p + geom_path() + labs(title = "geom_path")
p + geom_text(aes(label = label)) + labs(title = "geom_text")
p + geom_tile() + labs(title = "geom_tile")
p + geom_polygon() + labs(title = "geom_polygon")
5.4 展示数据分布
# 对于一维连续型分布,最重要的几何对象是直方图
# 可以改变组距宽度(binwidth)或者显示的精确指定切分位置(breaks)
# 有多种方法可以用来进行分布的跨组比较:
# 1,同时绘制多个小的直方图 facets = .~var
# 2,使用频率多边形 geom = "freqpoly"
# 3,使用条件密度图 position = "fill"
## 示例
depth_dist <- ggplot(diamonds,aes(depth)) + xlim(58,68)
depth_dist + geom_histogram(aes(y = ..density..),binwidth = 0.1) + facet_grid(cut ~ .)
depth_dist + geom_histogram(aes(fill = cut),binwidth = 0.1,position = "fill")
depth_dist + geom_freqpoly(aes(y = ..density..,colour = cut),binwidth = 0.1)
# 它们显示了一个有趣的模式:随着钻石质量的提高,分布逐渐向左偏移且愈发对称
# 永远不要指望依靠默认的参数就能对某个具体的分布获得一个表现力强的图形
# 针对类别型或连续型变量 绘制箱线图
# 连续型变量,必须设置group图形属性以得到多个箱线图
library(plyr)
qplot(cut,depth,data = diamonds,geom = "boxplot")
qplot(carat,depth,data = diamonds,geom = "boxplot",group = round_any(carat,0.1,floor),xlim = c(0,3))
# geom_jitter 通过在离散型分布上添加随机噪声以避免覆盖绘制问题,这是一种比较粗糙的方法
# 可以看到两次的jitter结果是不一样的
qplot(class,cty,data = mpg,geom = "jitter")
qplot(class,cty,data = mpg,geom = "jitter")
# geom_density 基于核平滑方法进行平滑后得到的频率多边形,请仅在已知潜在的密度分布为平滑、连续且无界的时候使用这种密度图
qplot(depth,data = diamonds,geom = "density",xlim = c(54,70))
qplot(depth,data = diamonds,geom = "density",xlim = c(54,70),fill = cut,alpha = I(0.2))
5.5 处理遮盖绘制问题
# 小规模的遮盖问题可以通过绘制更小的点加以缓解
df <- data.frame(x = rnorm(2000),y = rnorm(2000))
norm <- ggplot(df,aes(x,y))
norm + geom_point()
norm + geom_point(shape = 1)
norm + geom_point(shape = ".") ##点的大小为像素级
# 可以使用alpha 调整透明度
# R中,可用的最小透明度为 1/256
norm + geom_point(colour = "black",alpha = 1/3)
norm + geom_point(colour = "black",alpha = 1/5)
norm + geom_point(colour = "black",alpha = 1/10)
# 如果数据存在一定的离散性,可以通过在点上增加随机扰动(噪声)来减轻重叠。
# 特别是在与透明度一起使用时,这种方法很有效
td <- ggplot(diamonds,aes(table,depth)) + xlim(50,70) + ylim(50,70)
td + geom_point()
td + geom_jitter()
jit <- position_jitter(width = 0.5)
td + geom_jitter(position = jit)
td + geom_jitter(position = jit)
td + geom_jitter(position = jit,colour = "black",alpha = 1/10)
td + geom_jitter(position = jit,colour = "black",alpha = 1/200)
# 将点分箱并统计每个箱中点的数量
# 然后通过某种方式可视化这个数量
d <- ggplot(diamonds,aes(carat,price)) + xlim(1,3) + theme(legend.position = "none")
d + geom_point()
d + stat_bin2d()
d + stat_bin2d(bins = 10)
d + stat_bin2d(binwidth = c(0.02,200))
d + stat_binhex()
d + stat_binhex(bins = 10)
d + stat_binhex(binwidth = c(0.02,200))
# 使用stat_density2d作二维密度估计,并将"等高线"添加到散点图中
# 以着色瓦片直接展示密度,或使用大小与分布密度成比例的点进行展示
5.6 曲面图
# ggplot2 暂不支持真正的三维曲面图。
# 但具有在二维平面上展现三维曲面的常见工具:等高线图,着色瓦片以及气泡图
5.7 绘制地图
# maps包主要针对美国本土
# 添加地图边界可通过函数 borders()完成
install.packages("maps")
library(maps)
data("us.cities")
head(us.cities)
big_cities <- subset(us.cities,pop > 500000)
qplot(long,lat,data = big_cities) + borders("state",size = 0.5)
tx_cities <- subset(us.cities,country.etc == "TX")
ggplot(tx_cities,aes(long,lat)) + borders("county","texas",colour = "grey70") + geom_point(colour = "red",alpha = 0.5)
name country.etc pop lat long capital
1 Abilene TX TX 113888 32.45 -99.74 0
2 Akron OH OH 206634 41.08 -81.52 0
3 Alameda CA CA 70069 37.77 -122.26 0
4 Albany GA GA 75510 31.58 -84.18 0
5 Albany NY NY 93576 42.67 -73.80 2
6 Albany OR OR 45535 44.62 -123.09 0
# 等值线图
# 使用map_data()将地图数据转换为数据框
# 可以在之后通过merge() 操作与我们的数据相融合,最终绘制出等值线图
# 关键在于,我们的数据 和 地图数据中要有一列可以相互匹配
states <- map_data("state")
head(states)
arrests <- USArrests
names(arrests) <- tolower(names(arrests))
names(arrests)
arrests$region <- tolower(rownames(USArrests))
head(arrests)
choro <- merge(states,arrests,by = "region")
head(choro)
# 由于绘制多边形时 涉及顺序问题,且merge破坏了原始排序,故将行重新排序
choro <- choro[order(choro$order),]
qplot(long,lat,data = choro,group = group,fill = assault,geom = "polygon")
qplot(long,lat,data = choro,group = group,fill = assault/murder,geom = "polygon")