Расширить geom_vline за пределы графика

Я пытаюсь расширить строки geom_vline в моем графике ggplot, чтобы выйти за пределы области графика и в область оси. Цель этого состоит в том, чтобы эти линии разделяли метки осей, чтобы они могли выровняться с другим графиком, который идет рядом с ним (см. Ниже).

Некоторый короткий пример кода (у меня намного больше строк, и поэтому мне нужны горизонтальные линии, чтобы все было прямо):

library(ggplot2)
library(cowplot)
library(dplyr)

#play data set
cars.data <- mtcars %>%
      mutate(car_name = rownames(mtcars)) %>%
      slice(1:6)

#I would like vlines to be extend in this plot
p1 <- ggplot(cars.data, aes(x = car_name, y = hp)) +
    geom_point() +
    scale_x_discrete(position = "top") +
    coord_flip() +
    geom_vline(aes(xintercept = seq(1.5, 6.5, 1)), color = "gray60") +
    xlab("")


p2 <- ggplot(cars.data, aes(y = car_name, x = 1)) +
  geom_text(aes(label = disp)) +
  xlab("disp") +
  geom_hline(aes(yintercept = seq(1.5, 6.5, 1)), color = "gray60")+
  theme(axis.title.y = element_blank(),
        axis.title.x = element_text(vjust = 0.5, angle = 30),
        axis.text = element_blank(),
        axis.line = element_blank(),
        axis.ticks = element_blank(),
        panel.background = element_rect(fill = "gray90"))

plot_grid(p1, p2, rel_widths = c(1,0.2))

В результате получается следующий рисунок:

Я ищу, чтобы удлинить строки из p1так что они продолжаются между сюжетами, почти как гибрид сюжета и таблицы. я пыталсяclip = "off" но, похоже, это не помогает.

2 ответа

Решение

Вам нужно будет нарисовать линии самостоятельно, чтобы убедиться, что они могут выходить за границу графика, когда вы установите clip = "off". я используюgeom_segment() вот и вручную выставляем лимиты в координатах.

Вам также необходимо выровнять два графика в plot_grid() чтобы убедиться, что все работает правильно.

library(ggplot2)
library(cowplot)
library(dplyr)

#play data set
cars.data <- mtcars %>%
  mutate(car_name = rownames(mtcars)) %>%
  slice(1:6)

p1 <- ggplot(cars.data, aes(x = car_name, y = hp)) +
  geom_point() +
  scale_x_discrete(
    name = NULL,
    position = "top"
  ) +
  scale_y_continuous(expand = c(0, 0)) +
  coord_flip(clip = "off", ylim = c(80, 180)) +
  geom_segment(
    data = data.frame(x = seq(1.5, 6.5, 1), ymin = 80, ymax = 240),
    aes(x = x, xend = x, y = ymin, yend = ymax),
    inherit.aes = FALSE,
    color = "gray60"
  ) +
  xlab(NULL) +
  theme_cowplot()


p2 <- ggplot(cars.data, aes(y = car_name, x = 1)) +
  geom_text(aes(label = disp)) +
  xlab("disp") +
  geom_hline(aes(yintercept = seq(1.5, 6.5, 1)), color = "gray60") +
  theme_cowplot() +
  theme(
    axis.title.y = element_blank(),
    axis.title.x = element_text(vjust = 0.5, angle = 30),
    axis.text = element_blank(),
    axis.line = element_blank(),
    axis.ticks = element_blank(),
    panel.background = element_rect(fill = "gray90"),
    plot.margin = margin(7, 7, 7, 0)
  )

plot_grid(p1, p2, rel_widths = c(1,0.2), align = "h", axis = "bt")

Создано 2019-12-02 пакетом REPEX (v0.3.0)

Вот способ начать с того, что вместо того, чтобы полагаться на маркировку оси ggplot для получения того, что вы хотите, обрабатывает метки как данные и создает свои собственные. Возник вопрос, где мы использовали аналогичные подходы здесь: Гистограммы, соединенные линиями / Как соединить два графика, организованных сеткой. Упорядочить в R / ggplot2

Несколько уловок сделают эту работу:

  • Заменить метки осей выровненными по левому краю geom_text и масштабируйте расширение, чтобы разместить его правильно
  • Сделайте так, чтобы все геометрии использовали одну и ту же переменную оси x, чтобы коровский график мог выравниваться по этой оси
  • Установите отрицательные поля на сторонах, которые соединяются, чтобы панели переходили одна в другую и выглядели как непрерывный график.
library(ggplot2)
library(cowplot)
library(dplyr)

theme_set(theme_cowplot()) # I'm using cowplot v1.0.0 which no longer does this by default

p_left <- ggplot(cars.data, aes(x = car_name, y = hp)) +
  geom_vline(aes(xintercept = seq(1.5, 6.5, 1)), color = "gray60") +
  geom_point() +
  scale_x_discrete(breaks = NULL) +
  coord_flip() +
  xlab(NULL) +
  theme(axis.text.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.line = element_blank(),
        plot.margin = margin(5, -5, 5, 5, "pt"),
        panel.border = element_blank())

p_middle <- ggplot(cars.data, aes(x = car_name, y = 1)) +
  geom_vline(aes(xintercept = seq(1.5, 6.5, 1)), color = "gray60") +
  geom_text(aes(label = car_name), hjust = 0) +
  scale_x_discrete() +
  scale_y_continuous(expand = expansion(add = c(0.05, 0.5))) +
  coord_flip() +
  labs(x = NULL, y = "") +
  theme(axis.text = element_blank(),
        axis.ticks = element_blank(),
        axis.line = element_blank(),
        panel.grid = element_blank(),
        plot.margin = margin(5, -5, 5, -5, "pt"),
        panel.border = element_blank())

p_right <- ggplot(cars.data, aes(x = car_name, y = 1)) +
  geom_vline(aes(xintercept = seq(1.5, 6.5, 1)), color = "gray60") +
  geom_text(aes(label = disp)) +
  scale_x_discrete() +
  coord_flip() +
  labs(x = NULL, y = "disp") +
  theme(axis.text = element_blank(),
        axis.ticks = element_blank(),
        axis.line = element_blank(),
        panel.grid = element_blank(),
        plot.margin = margin(5, 5, 5, -5, "pt"),
        panel.border = element_blank())


plot_grid(p_left, p_middle, p_right,
  nrow = 1, rel_widths = c(1, 0.4, 0.2),
  align = "h"
)

Я скопировал только основные изменения темы - вы, вероятно, захотите изменить что-то в соответствии со своими целями. Я бы рекомендовал также копаться в каждом отдельном графике, чтобы корректировать их один за другим.

Другие вопросы по тегам