9.8 线条

9.8.1 问题

你想要把线条加到图上。

9.8.2 方案

9.8.2.1 使用一个连续轴和一个分类轴

  1. # 一些样本数据
  2. dat <- read.table(header = TRUE, text = "
  3. cond result
  4. control 10
  5. treatment 11.5
  6. ")
  7. library(ggplot2)
9.8.2.1.1 一条线段

这些使用 geom_hline(),因为y轴是连续的,但如果x轴是连续的,也可以使用 geom_vline()(带有 xintercept)。

  1. # 基本柱状条
  2. bp <- ggplot(dat, aes(x = cond, y = result)) + geom_bar(position = position_dodge(),
  3. stat = "identity")
  4. bp

9.8 线条 - 图1

  1. # 添加水平线
  2. bp + geom_hline(aes(yintercept = 12))

9.8 线条 - 图2

  1. # 使线条变红并变为虚线
  2. bp + geom_hline(aes(yintercept = 12), colour = "#990000",
  3. linetype = "dashed")

9.8 线条 - 图3

9.8.2.1.2 每个分类值的单独行

要为每个条形成单独的行,请使用 geom_errorbar()

  1. # 为每个条形绘制单独的线条。 首先添加另一列到目前为止
  2. dat$hline <- c(9, 12)
  3. dat
  4. #> cond result hline
  5. #> 1 control 10.0 9
  6. #> 2 treatment 11.5 12
  7. # 需要重新指定 bp,因为数据已经改变
  8. bp <- ggplot(dat, aes(x = cond, y = result)) + geom_bar(position = position_dodge(),
  9. stat = "identity")
  10. # 为每个柱状图画分开的线条
  11. bp + geom_errorbar(aes(ymax = hline, ymin = hline), colour = "#AA0000")

9.8 线条 - 图4

  1. # 让线条更细一点
  2. bp + geom_errorbar(width = 0.5, aes(ymax = hline, ymin = hline),
  3. colour = "#AA0000")

9.8 线条 - 图5

  1. # 即使我们从第二个数据框获得 hline
  2. # 值,也可以得到相同的结果 使用 hline 定义数据框
  3. dat_hlines <- data.frame(cond = c("control", "treatment"),
  4. hline = c(9, 12))
  5. dat_hlines
  6. #> cond hline
  7. #> 1 control 9
  8. #> 2 treatment 12
  9. # 柱状图形来自 dat,但是线条来自 dat_hlines
  10. bp + geom_errorbar(data = dat_hlines, aes(y = NULL, ymax = hline,
  11. ymin = hline), colour = "#AA0000")

9.8 线条 - 图6

9.8.2.1.3 分组栏上的线条

可以在分组条上添加线条。 在这个例子中,实际上有四行(hline 的每个条目一行),但它看起来像两个,因为它们是相互重叠的。 我不认为可以避免这种情况,但它不会导致任何问题。

  1. dat <- read.table(header = TRUE, text = "
  2. cond group result hline
  3. control A 10 9
  4. treatment A 11.5 12
  5. control B 12 9
  6. treatment B 14 12
  7. ")
  8. dat
  9. #> cond group result hline
  10. #> 1 control A 10.0 9
  11. #> 2 treatment A 11.5 12
  12. #> 3 control B 12.0 9
  13. #> 4 treatment B 14.0 12
  14. # 定义基本柱状图
  15. bp <- ggplot(dat, aes(x = cond, y = result, fill = group)) +
  16. geom_bar(position = position_dodge(), stat = "identity")
  17. bp

9.8 线条 - 图7

  1. # 误差线相互绘制 - 有四个但看起来像两个
  2. bp + geom_errorbar(aes(ymax = hline, ymin = hline), linetype = "dashed")

9.8 线条 - 图8

9.8.2.2 各个组合柱状图上的线条

即使在分组时,也可以在每个单独的条上划线。

  1. dat <- read.table(header = TRUE, text = "
  2. cond group result hline
  3. control A 10 11
  4. treatment A 11.5 12
  5. control B 12 12.5
  6. treatment B 14 15
  7. ")
  8. # 定义基本条形图
  9. bp <- ggplot(dat, aes(x = cond, y = result, fill = group)) +
  10. geom_bar(position = position_dodge(), stat = "identity")
  11. bp

9.8 线条 - 图9

  1. bp + geom_errorbar(aes(ymax = hline, ymin = hline), linetype = "dashed",
  2. position = position_dodge())

9.8 线条 - 图10

9.8.2.3 有两个连续轴

样本数据如下:

  1. dat <- read.table(header = TRUE, text = "
  2. cond xval yval
  3. control 11.5 10.8
  4. control 9.3 12.9
  5. control 8.0 9.9
  6. control 11.5 10.1
  7. control 8.6 8.3
  8. control 9.9 9.5
  9. control 8.8 8.7
  10. control 11.7 10.1
  11. control 9.7 9.3
  12. control 9.8 12.0
  13. treatment 10.4 10.6
  14. treatment 12.1 8.6
  15. treatment 11.2 11.0
  16. treatment 10.0 8.8
  17. treatment 12.9 9.5
  18. treatment 9.1 10.0
  19. treatment 13.4 9.6
  20. treatment 11.6 9.8
  21. treatment 11.5 9.8
  22. treatment 12.0 10.6
  23. ")
  24. library(ggplot2)
9.8.2.3.1 基础线条
  1. # 基本的散点图
  2. sp <- ggplot(dat, aes(x = xval, y = yval, colour = cond)) +
  3. geom_point()
  4. # 添加一个水平线条
  5. sp + geom_hline(aes(yintercept = 10))

9.8 线条 - 图11

  1. # 添加红色虚线垂直线
  2. sp + geom_hline(aes(yintercept = 10)) + geom_vline(aes(xintercept = 11.5),
  3. colour = "#BB0000", linetype = "dashed")

9.8 线条 - 图12

9.8.2.3.2 画线为平均值

还可以按一些变量分组计算每个数据子集的平均值。 组别必须计算并存储在单独的列中,最简单的方法是使用 dplyr 包。请注意,该行的 y 范围由数据确定。

  1. library(dplyr)
  2. #>
  3. #> Attaching package: 'dplyr'
  4. #> The following objects are masked from 'package:plyr':
  5. #>
  6. #> arrange, count, desc, failwith, id, mutate,
  7. #> rename, summarise, summarize
  8. #> The following object is masked from 'package:car':
  9. #>
  10. #> recode
  11. #> The following objects are masked from 'package:stats':
  12. #>
  13. #> filter, lag
  14. #> The following objects are masked from 'package:base':
  15. #>
  16. #> intersect, setdiff, setequal, union
  17. lines <- dat %>% group_by(cond) %>% summarise(x = mean(xval),
  18. ymin = min(yval), ymax = max(yval))
  19. # 为每组的平均 xval 添加彩色线条
  20. sp <- sp + geom_hline(aes(yintercept = 10)) + geom_linerange(aes(x = x,
  21. y = NULL, ymin = ymin, ymax = ymax), data = lines)
  22. sp

9.8 线条 - 图13

9.8.2.3.3 在分面使用线条

一般来说,如果你加一条线,它将出现在所有的分面上。

  1. # 分面,基于cond
  2. spf <- sp + facet_grid(. ~ cond)
  3. spf

9.8 线条 - 图14

  1. # 用相同的值在所有的分面上画水平线
  2. spf + geom_hline(aes(yintercept = 10))

9.8 线条 - 图15

如果你希望不同的线条出现在不同的方面,有两个选项。 一种是创建具有所需线条值的新数据框。 另一种选择(控制更有限)是在 geom_line() 中设定 statxintercept

  1. dat_vlines <- data.frame(cond = levels(dat$cond), xval = c(10,
  2. 11.5))
  3. dat_vlines
  4. #> cond xval
  5. #> 1 control 10.0
  6. #> 2 treatment 11.5
  7. spf + geom_hline(aes(yintercept = 10)) + geom_vline(aes(xintercept = xval),
  8. data = dat_vlines, colour = "#990000", linetype = "dashed")

9.8 线条 - 图16

  1. spf + geom_hline(aes(yintercept = 10)) + geom_linerange(aes(x = x,
  2. y = NULL, ymin = ymin, ymax = ymax), data = lines)

9.8 线条 - 图17