ggplot2中的小网格线,具有离散值和构面网格 [英] Minor grid lines in ggplot2 with discrete values and facet grid

查看:134
本文介绍了ggplot2中的小网格线,具有离散值和构面网格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a plot created using ggplot2 where I'm trying to modify some of the minor grid lines. Here is the current version:

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不适用于分类数据,即因子).

Y axis is a factor and a facet grid is used, with an uneven number of categories in each grid. I added some minor grid lines using geom_hline (my understanding is that panel.grid.minor does not work with categorical data i.e., factors).

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

I would like to remove the lines highlighted in yellow below, and then ADD a single black line in between the two facet grids (i.e., where the current double lines are that are highlighted in yellow).

有什么办法吗?我宁愿避免对任何行的位置进行硬编码,以防数据发生变化.谢谢.

Any way to do this? I'd prefer avoiding hard coding the position of any lines, in case the data change. Thanks.

推荐答案

动态删除顶部和底部网格线相对容易.您可以根据构面组对数据集中的行位置进行编码,并排除最大值和最小值,并在aes()语句内用xintercept绘制geom_hline.该方法对于更改数据非常可靠(要查看该方法是否在更改数据时起作用,请在下面的# filter(!is.na(birth_year))行中注释掉).

Removing the top and bottom grid lines dynamically is relatively easy. You code the line positions in the data set based on the faceting groups and exclude the highest and lowest value, and plot the geom_hline with an xintercept inside the aes() statement. That approach is robust to changing the data (to see that this approach works if you change the data, comment out the # filter(!is.na(birth_year)) line below).

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)

给予

但是,很难在刻面之间添加实体而不进行任何硬编码.有一些方法可以在构面之间添加边界(请参见此处) ,但是如果我们不知道构面是否发生变化,则应该为边框指定哪个值并不明显.我猜有一种可能的解决方案,那就是在绘图中绘制硬编码线以划分各个小平面,但棘手的部分是根据数据以及最终如何绘制这些小平面来动态确定该边界将要定位的位置(例如按什么顺序等).我有兴趣听取其他意见.

However, adding a solid between the facets without any hardcoding is difficult. There are some possible ways to add borders between facets (see here), but if we don't know whether the facets change it is not obvious to which value the border should be assigned. I guess there is a possible solution with drawing a hard coded line in the plot that divides the facets, but the tricky part is to determine dynamically where that border is going to be located, based on the data and how the facets are ultimately draw (e.g. in which order etc). I'd be interested in hearing other opinions on this.

这篇关于ggplot2中的小网格线,具有离散值和构面网格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆