9.1 条形图与线图
9.1.1 问题
你想要创建基本的条形图与线图
9.1.2 方案
想要使用 ggplot2 绘制图形,数据必须是一个数据框,而且必须是长格式。
9.1.2.1 基本图形,离散 x-axis
使用条形图,条形的高度通常代表这种不同的东西:
- 每一组事件的计数,通过
stat_bin()
指定,ggplot2 默认使用该选项 - 数据集中某一列的值,通过
stat_identity()
指定
x 轴 | 高度含义 | 名称 |
---|---|---|
连续 | 计数 | 直方图 |
离散 | 计数 | 条形图 |
连续 | 数值 | 条形图 |
离散 | 数值 | 条形图 |
9.1.2.1.1 有值的条形图
这里有一些样例数据 (抽自 reshape2 包的 tips
数据集):
dat <- data.frame(time = factor(c("Lunch", "Dinner"), levels = c("Lunch",
"Dinner")), total_bill = c(14.89, 17.23))
dat
#> time total_bill
#> 1 Lunch 14.89
#> 2 Dinner 17.23
# 导入 ggplot2 分析包
library(ggplot2)
在这些例子中,条形的高度代表数据框某一列的值,所以使用 stat="identity"
而不是默认的 stat="bin"
。
这里使用的映射变量为:
time
: x-axis 和填充颜色total_bill
: y-axis
# 非常基本的条形图
ggplot(data = dat, aes(x = time, y = total_bill)) + geom_bar(stat = "identity")
# 按时间填充颜色
ggplot(data = dat, aes(x = time, y = total_bill, fill = time)) +
geom_bar(stat = "identity")
## 这和上面是一样的结果 ggplot(data=dat, aes(x=time,
## y=total_bill)) + geom_bar(aes(fill=time),
## stat='identity') 添加黑色的边框线
ggplot(data = dat, aes(x = time, y = total_bill, fill = time)) +
geom_bar(colour = "black", stat = "identity")
# 没有图例,因为这个信息是多余的
ggplot(data = dat, aes(x = time, y = total_bill, fill = time)) +
geom_bar(colour = "black", stat = "identity") + guides(fill = FALSE)
一个理想的条形图可能是下面这样的:
# 添加题目,缩小箱宽,填充颜色,改变轴标签
ggplot(data = dat, aes(x = time, y = total_bill, fill = time)) +
geom_bar(colour = "black", fill = "#DD8888", width = 0.8,
stat = "identity") + guides(fill = FALSE) + xlab("Time of day") +
ylab("Total bill") + ggtitle("Average bill for 2 people")
查看颜色获取更多关于颜色的信息。
9.1.2.1.2 计数的条形图
在下面例子中,条形高度代表事件的计数。
我们直接使用 reshape2 的 tips
数据集。
library(reshape2)
# 查看头几行
head(tips)
#> total_bill tip sex smoker day time size
#> 1 16.99 1.01 Female No Sun Dinner 2
#> 2 10.34 1.66 Male No Sun Dinner 3
#> 3 21.01 3.50 Male No Sun Dinner 3
#> 4 23.68 3.31 Male No Sun Dinner 2
#> 5 24.59 3.61 Female No Sun Dinner 4
#> 6 25.29 4.71 Male No Sun Dinner 4
想要得到一个计数的条形图,不要映射变量到 y
,使用 stat="bin"
(默认就是这个) 而不是 stat="identity"
:
# 计数的条形图
ggplot(data = tips, aes(x = day)) + geom_bar(stat = "count")
## 和上面等同, 因为 stat='bin' 是默认 ggplot(data=tips,
## aes(x=day)) + geom_bar()
9.1.2.2 线图
对于线图,数据点必须分组从而 R 知道怎么连接这些点。如果只有一组的话,非常简单,设定 group=1
即可,如果是多组,需要设定分组变量。
下面是使用的映射变量:
time
: x 轴total_bill
: y 轴
# 基本的线图
ggplot(data = dat, aes(x = time, y = total_bill, group = 1)) +
geom_line()
## 与上面结果一致 ggplot(data=dat, aes(x=time,
## y=total_bill)) + geom_line(aes(group=1)) 添加点
ggplot(data = dat, aes(x = time, y = total_bill, group = 1)) +
geom_line() + geom_point()
# 改变线和点的颜色
# 改变线的类型和点的类型,用更粗的线、更大的点
# 用红色填充点
ggplot(data = dat, aes(x = time, y = total_bill, group = 1)) +
geom_line(colour = "red", linetype = "dashed", size = 1.5) +
geom_point(colour = "red", size = 4, shape = 21, fill = "white")
理想的线图可能像下面这样:
# 设定 y 轴的范围 改变轴标签
ggplot(data = dat, aes(x = time, y = total_bill, group = 1)) +
geom_line() + geom_point() + expand_limits(y = 0) +
xlab("Time of day") + ylab("Total bill") + ggtitle("Average bill for 2 people")
查看颜色获取更多关于颜色的信息。查看形状与线形 获取更多相关内容。
9.1.3 有更多变量的图
下面这个数据将用于接下来的例子
dat1 <- data.frame(sex = factor(c("Female", "Female", "Male",
"Male")), time = factor(c("Lunch", "Dinner", "Lunch",
"Dinner"), levels = c("Lunch", "Dinner")), total_bill = c(13.53,
16.81, 16.24, 17.42))
dat1
#> sex time total_bill
#> 1 Female Lunch 13.53
#> 2 Female Dinner 16.81
#> 3 Male Lunch 16.24
#> 4 Male Dinner 17.42
9.1.3.1 条形图
变量映射:
time
: x 轴sex
: 颜色填充total_bill
: y 轴
# 堆积条形图 -- 不常用
ggplot(data = dat1, aes(x = time, y = total_bill, fill = sex)) +
geom_bar(stat = "identity")
# 条形图,x 轴是 time, 颜色填充是 sex
ggplot(data = dat1, aes(x = time, y = total_bill, fill = sex)) +
geom_bar(stat = "identity", position = position_dodge())
ggplot(data = dat1, aes(x = time, y = total_bill, fill = sex)) +
geom_bar(stat = "identity", position = position_dodge(),
colour = "black")
# 改变颜色
ggplot(data = dat1, aes(x = time, y = total_bill, fill = sex)) +
geom_bar(stat = "identity", position = position_dodge(),
colour = "black") + scale_fill_manual(values = c("#999999",
"#E69F00"))
改变映射是非常容易的:
# 条形图,x 轴是性别,颜色是时间
ggplot(data = dat1, aes(x = sex, y = total_bill, fill = time)) +
geom_bar(stat = "identity", position = position_dodge(),
colour = "black")
查看颜色获取更多关于颜色的信息。
9.1.3.2 线图
变量映射:
time
: x 轴sex
: 线的颜色total_bill
: y 轴
想要绘制多条线,必须指定分组变量,否则所有点都将通过一条线进行连接。在这个例子中,我们希望通过性别来进行分组。
# 基本的带点线图
ggplot(data = dat1, aes(x = time, y = total_bill, group = sex)) +
geom_line() + geom_point()
# 将性别映射到颜色
ggplot(data = dat1, aes(x = time, y = total_bill, group = sex,
colour = sex)) + geom_line() + geom_point()
# 映射性别到不同的点类型
ggplot(data = dat1, aes(x = time, y = total_bill, group = sex,
shape = sex)) + geom_line() + geom_point()
# 使用更粗的线、更大的点
ggplot(data = dat1, aes(x = time, y = total_bill, group = sex,
shape = sex)) + geom_line(size = 1.5) + geom_point(size = 3,
fill = "white") + scale_shape_manual(values = c(22,
21))
更改颜色和线型变量的映射非常容易:
ggplot(data = dat1, aes(x = sex, y = total_bill, group = time,
shape = time, color = time)) + geom_line() + geom_point()
查看颜色获取更多关于颜色的信息。查看形状与线形获取更多相关内容。
9.1.3.3 完成的例子
完成的例子可能像下面这样:
# 一个条形图
ggplot(data=dat1, aes(x=time, y=total_bill, fill=sex)) +
geom_bar(colour="black", stat="identity",
position=position_dodge(),
size=.3) + # 更粗的线
scale_fill_hue(name="Sex of payer") + # 设定图例标题
xlab("Time of day") + ylab("Total bill") + # 设定轴标签
ggtitle("Average bill for 2 people") + # 设定题目
theme_bw()
# 一个线图
ggplot(data=dat1, aes(x=time, y=total_bill, group=sex, shape=sex, colour=sex)) +
geom_line(aes(linetype=sex), size=1) + # 按性别设定线型
geom_point(size=3, fill="white") + # 使用更大的点,并用颜色填充
expand_limits(y=0) + # 将 0 包含仅 y 轴
scale_colour_hue(name="Sex of payer", # 设定图例标题
l=30) + # 使用更深的颜色 (lightness=30)
scale_shape_manual(name="Sex of payer",
values=c(22,21)) + #
scale_linetype_discrete(name="Sex of payer") +
xlab("Time of day") + ylab("Total bill") + # 设定轴标签
ggtitle("Average bill for 2 people") + # 设定标题
theme_bw() +
theme(legend.position=c(.7, .4)) # 图例的位置
为了保证上图的图例一致,必须指定 3 次。至于为何如此,查看图例。
9.1.4 使用数值 x-axis
当 x 轴上的变量是数字时,有时需要将其视为连续变量,有时需要将其视为分类变量。在该数据集中,剂量应该是值为 0.5
, 1.0
和 2.0
的数值变量。作图时,将这些值视为相同类别可能很有用。
datn <- read.table(header = TRUE, text = "
supp dose length
OJ 0.5 13.23
OJ 1.0 22.70
OJ 2.0 26.06
VC 0.5 7.98
VC 1.0 16.77
VC 2.0 26.14
")
来自 ToothGrowth
数据集。
9.1.4.1 x-axis 作为连续变量
一个简单的图形可能会将剂量放在 x 轴,这种方式可以绘制一个线图。
ggplot(data = datn, aes(x = dose, y = length, group = supp,
colour = supp)) + geom_line() + geom_point()
9.1.4.2 x-axis 作为分类变量
首先,我们要将该变量转换为因子。
# 拷贝数据框并将它转换为因子
datn2 <- datn
datn2$dose <- factor(datn2$dose)
ggplot(data = datn2, aes(x = dose, y = length, group = supp,
colour = supp)) + geom_line() + geom_point()
# 使用原始的数据框,但使用 factor 函数在绘图时转换
ggplot(data = datn, aes(x = factor(dose), y = length, group = supp,
colour = supp)) + geom_line() + geom_point()
当连续值作为分类变量使用时,也可以绘制条形图。
ggplot(data = datn2, aes(x = dose, y = length, fill = supp)) +
geom_bar(stat = "identity", position = position_dodge())
ggplot(data = datn, aes(x = factor(dose), y = length, fill = supp)) +
geom_bar(stat = "identity", position = position_dodge())