Объедините базовую графику и графику ggplot в окне R figure
Я хотел бы создать фигуру, которая имеет комбинацию базовой графики и графики ggplot. Следующий код показывает мою фигуру, используя базовые функции построения графиков R:
t <- c(1:(24*14))
P <- 24
A <- 10
y <- A*sin(2*pi*t/P)+20
par(mfrow=c(2,2))
plot(y,type = "l",xlab = "Time (hours)",ylab = "Amplitude",main = "Time series")
acf(y,main = "Autocorrelation",xlab = "Lag (hours)", ylab = "ACF")
spectrum(y,method = "ar",main = "Spectral density function",
xlab = "Frequency (cycles per hour)",ylab = "Spectrum")
require(biwavelet)
t1 <- cbind(t, y)
wt.t1=wt(t1)
plot(wt.t1, plot.cb=FALSE, plot.phase=FALSE,main = "Continuous wavelet transform",
ylab = "Period (hours)",xlab = "Time (hours)")
Который генерирует
Большинство этих панелей выглядят достаточными для включения в мой отчет. Однако график, показывающий автокорреляцию, должен быть улучшен. Это выглядит намного лучше при использовании ggplot:
require(ggplot2)
acz <- acf(y, plot=F)
acd <- data.frame(lag=acz$lag, acf=acz$acf)
ggplot(acd, aes(lag, acf)) + geom_area(fill="grey") +
geom_hline(yintercept=c(0.05, -0.05), linetype="dashed") +
theme_bw()
Однако, поскольку ggplot не является базовым графиком, мы не можем объединить ggplot с layout или par(mfrow). Как я могу заменить график автокорреляции, сгенерированный из базовой графики, на график, сгенерированный ggplot? Я знаю, что могу использовать grid.arrange, если все мои фигуры были сделаны с помощью ggplot, но как мне это сделать, если в ggplot генерируется только один из графиков?
5 ответов
Используя пакет gridBase, вы можете сделать это, просто добавив 2 строки. Я думаю, что если вы хотите сделать забавный сюжет с сеткой, вам нужно просто понять и освоить видовые окна. Это действительно основной объект грид-пакета.
vps <- baseViewports()
pushViewport(vps$figure) ## I am in the space of the autocorrelation plot
Функция baseViewports() возвращает список из трех видовых экранов сетки. Я использую здесь изображение. Окно просмотра. Окно просмотра, соответствующее области рисунка текущего графика.
Вот как выглядит окончательное решение:
library(gridBase)
par(mfrow=c(2, 2))
plot(y,type = "l",xlab = "Time (hours)",ylab = "Amplitude",main = "Time series")
plot(wt.t1, plot.cb=FALSE, plot.phase=FALSE,main = "Continuous wavelet transform",
ylab = "Period (hours)",xlab = "Time (hours)")
spectrum(y,method = "ar",main = "Spectral density function",
xlab = "Frequency (cycles per hour)",ylab = "Spectrum")
## the last one is the current plot
plot.new() ## suggested by @Josh
vps <- baseViewports()
pushViewport(vps$figure) ## I am in the space of the autocorrelation plot
vp1 <-plotViewport(c(1.8,1,0,1)) ## create new vp with margins, you play with this values
require(ggplot2)
acz <- acf(y, plot=F)
acd <- data.frame(lag=acz$lag, acf=acz$acf)
p <- ggplot(acd, aes(lag, acf)) + geom_area(fill="grey") +
geom_hline(yintercept=c(0.05, -0.05), linetype="dashed") +
theme_bw()+labs(title= "Autocorrelation\n")+
## some setting in the title to get something near to the other plots
theme(plot.title = element_text(size = rel(1.4),face ='bold'))
print(p,vp = vp1) ## suggested by @bpatiste
Вы можете использовать команду печати с гробом и окном просмотра.
Сначала нарисуйте основную графику, затем добавьте ggplot
library(grid)
# Let's say that P is your plot
P <- ggplot(acd, # etc... )
# create an apporpriate viewport. Modify the dimensions and coordinates as needed
vp.BottomRight <- viewport(height=unit(.5, "npc"), width=unit(0.5, "npc"),
just=c("left","top"),
y=0.5, x=0.5)
# plot your base graphics
par(mfrow=c(2,2))
plot(y,type #etc .... )
# plot the ggplot using the print command
print(P, vp=vp.BottomRight)
cowplot
пакет имеет recordPlot()
функция для захвата базовых графиков R, так что они могут быть объединены в plot_grid()
функция.
library(biwavelet)
library(ggplot2)
library(cowplot)
t <- c(1:(24*14))
P <- 24
A <- 10
y <- A*sin(2*pi*t/P)+20
plot(y,type = "l",xlab = "Time (hours)",ylab = "Amplitude",main = "Time series")
### record the previous plot
p1 <- recordPlot()
spectrum(y,method = "ar",main = "Spectral density function",
xlab = "Frequency (cycles per hour)",ylab = "Spectrum")
p2 <- recordPlot()
t1 <- cbind(t, y)
wt.t1=wt(t1)
plot(wt.t1, plot.cb=FALSE, plot.phase=FALSE,main = "Continuous wavelet transform",
ylab = "Period (hours)",xlab = "Time (hours)")
p3 <- recordPlot()
acz <- acf(y, plot=F)
acd <- data.frame(lag=acz$lag, acf=acz$acf)
p4 <- ggplot(acd, aes(lag, acf)) + geom_area(fill="grey") +
geom_hline(yintercept=c(0.05, -0.05), linetype="dashed") +
theme_bw()
### combine all plots together
plot_grid(p1, p4, p2, p3,
labels = 'AUTO',
hjust = 0, vjust = 1)
Создано 2019-03-17 пакетом представлением (v0.2.1.9000)
Я фанат пакета gridGraphics. По какой-то причине у меня были проблемы с gridBase.
library(ggplot2)
library(gridGraphics)
data.frame(x = 2:10, y = 12:20) -> dat
plot(dat$x, dat$y)
grid.echo()
grid.grab() -> mapgrob
ggplot(data = dat) + geom_point(aes(x = x, y = y))
pushViewport(viewport(x = .8, y = .4, height = .2, width = .2))
grid.draw(mapgrob)
Другой вариант — использовать пакет ggplotify с функцией as.ggplot , которая преобразует базовый граф R в объект. Затем вы можете совместить этот сюжет с реальнымggplot
с использованиемpatchwork
структура макета. Вот воспроизводимый пример:
set.seed(1) # Reproducible
df <- data.frame(x = runif(10,0,1),
y = runif(10,0,1))
library(ggplot2)
library(ggplotify)
library(patchwork)
# ggplot
p_ggplot <- ggplot(df, aes(x = x, y = y)) +
geom_point()
# Combine base graph and ggplot
as.ggplot(~plot(df$x, df$y)) + p_ggplot
Создано 22 августа 2022 г. с репрексом v2.0.2
Как видите, базовый график и график ggplot объединены в одном окне рисунка.
Можно комбинировать более разные типы графических объектов, как описано в документации:
Преобразуйте вызов функции построения графика (используя выражение или формулу) в объект 'grob' или 'ggplot', совместимый с экосистемой 'grid' и 'ggplot2'. С помощью этого пакета мы можем, например, использовать 'cowplot' для выравнивания графиков, созданных 'базовой' графикой, 'сеткой', 'решеткой', 'vcd' и т. д., путем преобразования их в объекты 'ggplot'.