ggplot2中的次要网格线,具有离散值和构面网格

时间:2017-07-04 10:41:25

标签: r ggplot2

我有一个使用ggplot2创建的绘图,我正在尝试修改一些次要的网格线。这是当前版本:

library(tidyverse)

data(starwars)
starwars = starwars %>% 
  filter(!is.na(homeworld), !is.na(skin_color)) %>%
  mutate(tatooine = factor(if_else(homeworld == "Tatooine", "Tatooine Native", "Other Native")),
         skin_color = factor(skin_color))

ggplot(starwars, aes(birth_year, skin_color)) +
  geom_point(aes(color = gender), size = 4, alpha = 0.7, show.legend = FALSE) +
  facet_grid(tatooine ~ ., scales = "free_y", space = "free_y", switch = "y") +
  theme_minimal() + 
  theme(
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    strip.placement = "outside",
    strip.background = element_rect(fill="gray90", color = "white"),
  ) + 
  geom_hline(yintercept = seq(0, length(unique(starwars$skin_color))) + .5, color="gray30")

Y轴是一个因子,使用了一个构面网格,每个网格中的类别数量不均匀。我使用geom_hline添加了一些小的网格线(我的理解是panel.grid.minor不适用于分类数据,即因素)。

我想删除下面以黄色突出显示的行,然后在两个构面网格之间添加一条黑线(即,当前双线以黄色突出显示)。

有什么办法吗?如果数据发生变化,我宁愿避免硬编码任何行的位置。感谢。

enter image description here

1 个答案:

答案 0 :(得分:1)

动态删除顶部和底部网格线相对容易。您可以根据构面组对数据集中的线位置进行编码,并排除最高和最低值,并在geom_hline语句中将xinterceptaes()进行对比。这种方法对于更改数据非常有用(如果您更改数据,请注意此方法有效,请注释掉下面的# filter(!is.na(birth_year))行。)

library(tidyverse)
library(grid)

data(starwars)
starwars = starwars %>% 
  filter(!is.na(homeworld), !is.na(skin_color)) %>%
  mutate(tatooine = factor(if_else(homeworld == "Tatooine", "Tatooine Native", "Other Native")),
         skin_color = factor(skin_color)) %>% 
  # filter(!is.na(birth_year)) %>% 
  group_by(tatooine) %>% 

  # here we assign the line_positions
  mutate(line_positions = as.numeric(factor(skin_color, levels = unique(skin_color))), 
         line_positions = line_positions + .5,  
         line_positions = ifelse(line_positions == max(line_positions), NA, line_positions)) 


plot_out <- ggplot(starwars, aes(birth_year, skin_color)) +
  geom_point(aes(color = gender), size = 4, alpha = 0.7, show.legend = FALSE) +
  geom_hline(aes(yintercept = line_positions)) + 
  facet_grid(tatooine ~ ., scales = "free_y", space = "free_y", switch = "y") +
  theme_minimal() + 
  theme(
    panel.grid.major.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_line(colour = "black"),
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    strip.placement = "outside",
    strip.background = element_rect(fill="gray90", color = "white"), 

  ) 

print(plot_out)

给出

enter image description here

然而,在没有任何硬编码的情况下在小平面之间添加实体是困难的。有一些可能的方法可以在构面之间添加边框(请参阅here),但如果我们不知道构面是否发生更改,则应该分配边框的值不明显。我猜有一种可能的解决方案是在图中划分硬编码线来划分小平面,但是棘手的部分是根据数据以及小平面最终绘制的方式动态确定边界的位置(例如以哪种顺序等)。我有兴趣听到其他意见。