Добавить geom_bar с собственным фреймом данных к существующему ggplot2 - PullRequest
0 голосов
/ 04 августа 2020

Этот "ручной" рисунок иллюстрирует, что я хотел бы создать с помощью ggplot2

Я хочу построить временные рамки (от start до end) и указать c временные точки (point) от людей как geom_linerange и geom_point, соответственно. Это хорошо работает. Но, кроме того, я хочу отображать на тех же графиках столбцы, указывающие количество статей, опубликованных до определенного c года (фрейм данных m). Для количества статей необходима собственная перевернутая ось x, указывающая количество статей). Как я могу добавить эту информацию?

d <- data.frame(name=c("Frank", "Thomas", "Mike", "Ronny"),
                start=c(2010, 2013, 2014, 2017),
                end=c(2012, 2017, 2017, 2019),
                point=c(2014, 2017, 2018, 2020))

m <- data.frame(y=c(2010, 2011, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020),
                n=c(1, 3, 4, 10, 20, 25, 30, 37, 42, 50))


ggplot(d, aes(x=name, y=point, ymin=start, ymax=end)) +
  geom_linerange(size=2, color="#ff546a") +
  geom_point(size=2, color="#127999") +
  coord_flip() +
  theme_bw() + # white background
  scale_y_continuous("", limits=c(2000, 2020), breaks=seq(2000, 2020, 5), labels=seq(2000, 2020, 5)) +
  xlab("")

введите описание изображения здесь

1 Ответ

1 голос
/ 04 августа 2020

вы можете попробовать 1. решение коровьего заговора

p1 <- ggplot(d, aes(x=name, y=point, ymin=start, ymax=end)) +
  geom_linerange(size=2, color="#ff546a") +
  geom_point(size=2, color="#127999") +
  coord_flip() +
  theme_bw() + # white background
  scale_y_continuous("", limits=c(2000, 2020), breaks=seq(2000, 2020, 5), labels=seq(2000, 2020, 5)) +
  xlab("") 


p2 <- ggplot(m, aes(x=y, y=n)) + 
   geom_col(alpha=0.1) +
  theme_void() +
  scale_y_continuous(position = "right") +
  scale_x_continuous("", limits=c(2000, 2020), breaks=seq(2000, 2020, 5), labels=seq(2000, 2020, 5)) +
  theme(
    panel.grid.major = element_blank(),
    axis.line.x = element_blank(),
    # axis.text.x = element_blank(),
    axis.title.x = element_blank(),
    axis.ticks = element_blank(),
    axis.ticks.length = grid::unit(0, "pt"),
    axis.text.y = element_text(color = "black"),
    axis.text.x = element_text(color = "black"),
    axis.title.y = element_text(color = "black")
  )

p2

aligned_plots <- cowplot::align_plots(p1, p2, align="hv", axis="tblr")
cowplot::ggdraw(aligned_plots[[1]]) + cowplot::draw_plot(aligned_plots[[2]])

enter image description here

In the end you have to uncomment this line

# axis.text.x = element_blank(),

and remove this one:

axis.text.x = element_text(color = "black")

I leave it like this to show that the x axis shows the correct data with same scaling.

or a more general way (2.) by including all data into one data.frame and adding a second axis.

library(tidyverse)
left_join(m, d, by= c("y" = "start")) %>% 
  mutate(n_name= as.numeric(factor(name)),
         n_name = n_name*max(n)/max(n_name, na.rm = T)) %>% 
{ ggplot(.) + 
  geom_col(aes(y, n)) +
  geom_point(data = . %>% filter(!is.na(name)),
             aes(x=point, y=n_name),
             size=2, color="#127999") +
  geom_linerange(data = . %>% filter(!is.na(name)),
                 aes(x=point, y=n_name, xmin=y, xmax=end),
    size=2, color="#ff546a") +
  scale_x_continuous("", limits=c(2000, 2020), breaks=seq(2000, 2020, 5), labels=seq(2000, 2020, 5)) + 
  scale_y_continuous("", breaks = .$n_name[!is.na(.$n_name)],
                         labels = .$name[!is.na(.$n_name)],
                     sec.axis = sec_axis(~ .))}

введите описание изображения здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...