#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. Вау …… большое вам спасибо за ваш быстрый и полезный ответ. Я действительно ценю это! Избавил меня от настоящей головной боли 🙂 🙂