Параллельный график с одной легендой в ggplot2

#r #ggplot2 #graph #legend #side-by-side

#r #ggplot2 #График #легенда #параллельный

Вопрос:

Я хотел бы знать, как использовать ggplot2 для создания параллельных графиков с одной общей легендой. Я видел несколько похожих вопросов, но не уверен, как напрямую применить его к моему коду. Я предоставил свой код для графиков с легендой и некоторыми данными, которые можно использовать для воссоздания графиков.

 Stocks1<-c(2,1,0.8,0.7,0.6)
Bonds1<-c(1,0.8,0.7,0.6,0.5)
Cash1<-1-(Stocks1 Bonds1)
Stocks2<-c(0.6,0.5,0.4,0.3,0.2)
Bonds2<-c(0.3,0.2,0.2,0.15,0.1)
Cash2<-1-(Stocks2 Bonds2)
H<-length(Stocks1) #Change value to represent data
t <- seq(from = 0, to = H, 1) # time grid
  

И вот два графика

 pi_F<- data.frame(cash = Cash1,  bonds = Bonds1,   
                  stocks= Stocks1,time=t[-1])
melted_F   <- melt(pi_F, id.vars = 'time')

ggplot(melted_F, aes(x=time, y=value, group = variable))  
  geom_area(aes(fill=variable))  
  scale_fill_manual(values=c("#2E318F", "#DFAE41","#109FC6"),
                    name="Asset Type",
                    labels = c("Bank account","Bonds", "Stocks")) 
  scale_x_continuous(name = 'Age',
                     breaks = seq(1,H,1))   
  scale_y_continuous(name = 'Asset allocation (in %)',
                     labels=scales::percent,
                     breaks = seq(0,1,0.1),
                     sec.axis = sec_axis(~.*1,breaks =  seq(0,1,0.1),labels=scales::percent))   
  coord_cartesian(xlim = c(1,H), ylim = c(0,1), expand = TRUE)  
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())

pi_F<- data.frame(cash = Cash2,  bonds = Bonds2,   
                  stocks= Stocks2,time=t[-1])
melted_F   <- melt(pi_F, id.vars = 'time')

ggplot(melted_F, aes(x=time, y=value, group = variable))  
  geom_area(aes(fill=variable))  
  scale_fill_manual(values=c("#2E318F", "#DFAE41","#109FC6"),
                    name="Asset Type",
                    labels = c("Bank account","Bonds", "Stocks")) 
  scale_x_continuous(name = 'Age',
                     breaks = seq(1,H,1))   
  scale_y_continuous(name = 'Asset allocation (in %)',
                     labels=scales::percent,
                     breaks = seq(0,1,0.1),
                     sec.axis = sec_axis(~.*1,breaks =  seq(0,1,0.1),labels=scales::percent))   
  coord_cartesian(xlim = c(1,H), ylim = c(0,1), expand = TRUE)  
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())
  

В идеале я хотел бы, чтобы они были рядом с легендой в соответствующем месте, возможно, справа от обоих графиков. Заранее спасибо за помощь!

Комментарии:

1. Не присваивайте разным фреймам данных одно и то же имя — это сбивает с толку.

2. Я считаю, что самый простой способ сделать это — использовать пакет patchwork , созданный человеком, который сейчас поддерживает ggplot2 . Назвав два графика (например g1 , и g2 ), вы затем вызываете: g1 g2 plot_layout(guides = 'collect')

3. @p0bs Очень элегантное решение. Спасибо!

Ответ №1:

Объедините свои данные и используйте фасеты:

 ## calling the first data `melted_F` and the second `melted_F2`
## put them in one data frame with a column named "data" to tell
## which is which
melted = dplyr::bind_rows(list(data1 = melted_F, data2 = melted_F2), .id = "data")

## exact same plot code until the last line
ggplot(melted, aes(x=time, y=value, group = variable))  
  geom_area(aes(fill=variable))  
  scale_fill_manual(values=c("#2E318F", "#DFAE41","#109FC6"),
                    name="Asset Type",
                    labels = c("Bank account","Bonds", "Stocks")) 
  scale_x_continuous(name = 'Age',
                     breaks = seq(1,H,1))   
  scale_y_continuous(name = 'Asset allocation (in %)',
                     labels=scales::percent,
                     breaks = seq(0,1,0.1),
                     sec.axis = sec_axis(~.*1,breaks =  seq(0,1,0.1),labels=scales::percent))   
  coord_cartesian(xlim = c(1,H), ylim = c(0,1), expand = TRUE)  
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())  
  ##  facet by the column that identifies the data source
  facet_wrap(~ data)
  

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

Комментарии:

1. Вау …… большое вам спасибо за ваш быстрый и полезный ответ. Я действительно ценю это! Избавил меня от настоящей головной боли 🙂 🙂