如何使用 ggplot 突出显示更改线型或大小的线的特定区域

How to highlight a specific region of a line changing linetype or size using ggplot

我有以下数据框:

test = structure(list(Student = c("Ana", "Brenda", "Max", "Ana", "Brenda", 
"Max", "Ana", "Brenda", "Max"), Month = structure(c(1L, 1L, 1L, 
2L, 2L, 2L, 3L, 3L, 3L), .Label = c("January", "February", "March"
), class = "factor"), Grade = c(7L, 6L, 7L, 8L, 6L, 7L, 5L, 10L, 
10L), Change = c("February", "February", "February", "February", 
"February", "February", "February", "February", "February")), row.names = c(NA, 
-9L), class = "data.frame")

我绘制了每个学生几个月的成绩,想知道是否有一种简单的方法可以突出每条绘制线的特定部分,该部分对应于表现出最大变化的时间段成绩(此信息已存在于数据集中:“更改”列。在这种情况下,对于所有学生来说,这将是从二月到三月)。

尝试使用与呈现的类似逻辑 here, to change the color a specific part of the line 我试图更改线条的线型 and/or 大小(因为我已经使用颜色来分组和显示每个学生)以便突出显示该行的特定部分。然而,它似乎并不那么简单。

我的尝试如下:

ggplot(test, aes(x = Month, y = Grade, color = Student, group = Student)) + 
+     geom_point() + geom_line(data = test, aes(linetype = (ifelse(Month == Change, "solid", "dashed")))) 

产生错误:

Error: geom_path: If you are using dotted or dashed lines, colour, size and linetype must be constant over the line

ggplot(test, aes(x = Month, y = Grade, color = Student, group = Student)) + 
    geom_point() + geom_line(data = test, aes(size = (ifelse(Month == Change, 1, 0.8)))) 

哪种方式符合我的要求,但看起来很糟糕,而且看起来不像是使用我要指定的线的大小:

我该如何解决?提前致谢! n_n

不要在 aes 中指定大小。使用比例函数

关于线路设计的另一个建议见下文。

test = structure(list(Student = c("Ana", "Brenda", "Max", "Ana", "Brenda", 
                                  "Max", "Ana", "Brenda", "Max"), Month = structure(c(1L, 1L, 1L, 
                                                                                      2L, 2L, 2L, 3L, 3L, 3L), .Label = c("January", "February", "March"
                                                                                      ), class = "factor"), Grade = c(7L, 6L, 7L, 8L, 6L, 7L, 5L, 10L, 
                                                                                                                      10L), Change = c("Februrary", "Februrary", "Februrary", "Februrary", 
                                                                                                                                       "Februrary", "Februrary", "Februrary", "Februrary", "Februrary"
                                                                                                                      )), row.names = c(NA, -9L), class = "data.frame")
## typo corrected
test$Change <- "February"

library(ggplot2)

ggplot(test, aes(x = Month, y = Grade, color = Student, group = Student)) + 
  geom_point() +
  ## don't specify size in aes
  geom_line(data = test, aes(size = Month == Change)) +
  ## change the size scale
  scale_size_manual(values = c(`TRUE` = 2, `FALSE` = .8))

另一种选择可能是使用 ggforce::geom_link 函数,它在两点之间插入美学。

library(ggforce)

ggplot(test, aes(x = Month, y = Grade, color = Student, group = Student)) + 
  geom_point() +
  geom_link2(data = test, aes(size = Grade, ), lineend = "round") 

尝试更改线型时失败。在这种情况下,请改用 geom_segment - 不过您需要进行一些数据转换。

library(tidyverse)

test %>%
  group_by(Student) %>%
  mutate(xend = lead(Month), yend = lead(Grade)) %>%
ggplot(aes(x = Month, y = Grade, color = Student, group = Student)) + 
  geom_point() +
  geom_segment(aes(xend = xend, yend = yend, linetype = Month == Change)) +
  # need to specify your x
  scale_x_discrete(limits = unique(test$Month))
#> Warning: Removed 3 rows containing missing values (geom_segment).

沿其路线改变线条宽度是可能的(正如 tjebo 指出的那样),但它很少能制作出漂亮的情节。更清晰的方法可能是简单地在感兴趣的区域添加彩色背景:

library(hrbrthemes)
library(ggplot2)

ggplot(test, aes(x = Month, y = Grade, color = Student, group = Student)) +
  geom_point(alpha = 0) +
  geom_rect(data = test[1,],
            aes(xmin = 'February', xmax = 'March', ymin = -Inf, ymax = Inf),
            color = NA, fill = 'deepskyblue4', alpha = 0.1) +
  geom_line(size = 1) +
  geom_point(shape = 21, fill = 'white', size = 3) +
  theme_minimal() +
  scale_color_manual(values = c('pink3', 'orange2', 'red4')) +
  theme_tinyhand()