简体   繁体   中英

Add geom_bar with own data frame to an existing ggplot2

This "handmalde" figure illustrates what I would like to create with ggplot2

I want to plot time frames (from start to end ) and specific time points ( point ) from persons as geom_linerange and geom_point, respectively. That works well. But in addition, I want to show on the same plot bars indicating the number of articles published until a specific year (data frame m ). The number of articles need their own flipped x-axis indicating the number of articles). How can I add this information?

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("")

在此处输入图像描述

you can try a 1. cowplot solution

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]])

在此处输入图像描述

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(~ .))}

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM