theme_bw()去除了ggplot的所有颜色

时间:2018-10-02 13:14:23

标签: r ggplot2

library(tidyverse)
ggplot(mtcars, aes(cyl, mpg)) + 
  geom_point() + 
  theme_bw() + 
  geom_hline(aes(yintercept = 20), color = "red")

上面的代码是漂亮的黑白主题,带有红色水平线。下面的代码也应该是黑色和白色主题,这次有一条红色的垂直线。但是情节根本没有任何色彩。为什么theme_bw()从下面的图中去除所有颜色?

library(tidyverse)
library(lubridate)

df <- 
  tibble(
    date = as.Date(41000:42000, origin = "1899-12-30"), 
    value = c(rnorm(500, 5), rnorm(501, 10))
  ) %>% 
  mutate(year = as.factor(year(date)))

ggplot(df, aes(date, value)) + 
  geom_line() + 
  geom_vline(
    xintercept = as.numeric(df$date[yday(df$date) == 1]), color = "red"
  ) + 
  scale_x_date(
    date_labels = "%b", breaks = scales::pretty_breaks(), expand = c(0, 0)
  ) +
  facet_grid(.~ year, space = 'free_x', scales = 'free_x', switch = 'x') +
  labs(x = "") +
  theme_bw(base_size = 14, base_family = 'mono') +
  theme(panel.grid.minor.x = element_blank()) + 
  theme(panel.spacing.x = unit(0, "line")) +
  theme(strip.placement = 'outside', strip.background.x = element_blank()) 

enter image description here

2 个答案:

答案 0 :(得分:1)

您可以删除panel.border = element_blank()内带有theme的刻面面板边框

ggplot(df, aes(date, value)) +
  geom_line() +
  geom_vline(
    xintercept = as.numeric(df$date[yday(df$date) == 1]), color = "red") +
  scale_x_date(
    date_labels = "%b", breaks = scales::pretty_breaks(), expand = c(0, 0)) +
  facet_grid(.~ year, space = 'free_x', scales = 'free_x', switch = 'x') +
  labs(x = "") +
  theme_bw(base_size = 14, base_family = 'mono') +
  theme(
      panel.grid.minor.x = element_blank(),
      panel.spacing.x = unit(0, "line"),
      panel.border = element_blank(),
      strip.placement = 'outside',
      strip.background.x = element_blank())

enter image description here


更新

要使用构面,使红线不与构面边界重叠,这是一种“ hacky”解决方案:

首先,绘制无面板边框

gg <- ggplot(df, aes(date, value)) +
      geom_line() +
      geom_vline(
        xintercept = as.numeric(df$date[yday(df$date) == 1]), color = "red") +
      scale_x_date(
        date_labels = "%b", breaks = scales::pretty_breaks(), expand = c(0, 0)) +
      facet_grid(.~ year, space = 'free_x', scales = 'free_x', switch = 'x') +
      labs(x = "") +
      theme_bw(base_size = 14, base_family = 'mono') +
      theme(
          panel.grid.minor.x = element_blank(),
          panel.spacing.x = unit(0, "line"),
          panel.border = element_blank(),
          strip.placement = 'outside',
          strip.background.x = element_blank())

然后我们提取面板的y轴范围,并添加一个geom_rect来手动绘制面板边框

ylim <- ggplot_build(gg)$layout$panel_params[[1]]$y.range
gg <- gg +
    geom_rect(
        xmin = min(df$date), xmax = max(df$date),
        ymin = ylim[1], ymax = ylim[2],
        fill = NA, colour = "black")

enter image description here

这有点麻烦,因为您需要将绘图分成两步才能提取面板的y轴范围。

答案 1 :(得分:1)

另一个技巧,如果您愿意深入研究这些怪胎:

gp <- ggplotGrob(p) # where p is the original ggplot object

# for each panel grob, change the order of grobs such that the grob corresponding
# to geom_vline (should have a name like "GRID.segments.XXXX") lies above the grob
# corresponding to the facet outline (should have a name like "panel.border..rect.XXXX")
for(i in grep("panel", gp$layout$name)){
  old.order <- gp$grobs[[i]]$childrenOrder
  new.order <- c(old.order[-grep("segments", old.order)],
                 old.order[grep("segments", old.order)])
  gp$grobs[[i]]$childrenOrder <- new.order
}

grid::grid.draw(gp)

plot