I am trying to save a plot with ggsave(). I enter the following:
library(ggplot2)
Test = data.frame("X" = seq(1, 10, 1), "Y" = 2*seq(1, 10, 1))
P = ggplot(
Test, aes(x=X, y=Y))+
geom_line()
ggsave(P, "test.pdf", device = "pdf")
But get the error:
Saving 7 x 7 in image
Error in UseMethod("grid.draw") :
no applicable method for 'grid.draw' applied to an object of class "character"
asked Apr 2, 2017 at 16:35
Michael OhlroggeMichael Ohlrogge
10.3k5 gold badges46 silver badges74 bronze badges
Many R functions that save data, such as write.table(), saveRDS() etc. take as their first argument the object to be saved. But, this is not true for ggsave(). Instead, by default, its first argument is the name of the file to save to. Thus, the syntax above would need to be modified in one of two ways:
ggsave(plot = P, filename = "test.pdf", device = "pdf")
ggsave("test.pdf", P, device = "pdf")
answered Apr 2, 2017 at 16:35
Michael OhlroggeMichael Ohlrogge
10.3k5 gold badges46 silver badges74 bronze badges
2
I think it could work even without adding the path parameter, it will automatically save to the downloads folder.
answered Aug 16, 2022 at 0:56
1
Im getting a similar error. Please see my code below.
fit<- survfit(Surv(time, dead) ~ copy_number, data = datain)
p <- ggsurvplot(fit, conf.int = TRUE, pval = TRUE,
main = «Survival»,
palette = c(«#ff0000», «#0000ff»),
font.main = c(10, «bold»),
font.x = c(8, «bold»),
font.y = c(8, «bold»),
font.tickslab = c(6, «bold»),
pval.size = 2,
size = 0.2,
censor.size = 1,
legend = «bottom»
)
p$plot <- p$plot + theme(legend.text = element_text(size = 4),
legend.title = element_text(«», size = 4),
legend.key.size = unit(0.2, «cm»))
ggsave(filename= «/home/philserver/Desktop/mt_amp.tiff», print(p), device = «tiff», height = 2, width = 2, dpi = 300)
Error in UseMethod(«grid.draw») :
no applicable method for ‘grid.draw’ applied to an object of class «list»
In spite of this error, the plot is still saved. However, the error stops the R pipeline I have written, and the other dozen graphs in my pipeline are not generated. Is there a way to resolve the issue of saving ggsurvplots without throwing an error?
DISCLOSURE: I’m not sure how to make a reproducible example for this question.
I’m trying to plot a list of grobs using the gridExtra package.
I have some code that looks like this:
## Make Graphic Objects for Spec and raw traces
for (i in 1:length(morletPlots)){
gridplots_Spec[[i]]=ggplotGrob(morletPlots[[i]])
gridplots_Raw[[i]]=ggplotGrob(rawPlot[[i]])
gridplots_Raw[[i]]$widths=gridplots_Spec[[i]]$widths
}
names(gridplots_Spec)=names(morletPlots)
names(gridplots_Raw)=names(rawPlot)
## Combine spec and Raw traces
g=list()
for (i in 1:length(rawPlot)){
g[[i]]=arrangeGrob(gridplots_Spec[i],gridplots_Raw[i],heights=c(4/5,1/5))
}
numPlots = as.numeric(length(g))
##Plot both
for (i in 1:numPlots){
grid.draw(g[i],ncol=2)
}
Let me walk through the code.
morletPlots = a list of ggplots
rawplot = A list of ggplots
gridplots_spec and gridplots_Raw = list of grobs from the ggplots made above.
g = a list of the two grobs above combined so combining gridplots_spec[1] and gridplots_raw[1] so on and so on for the length of the list.
now my goal would be two plot all of those into 2 columns. But whenever I pass the gridplots_spec[i] through the grid.draw loop I get an error:
Error in UseMethod("grid.draw") :
no applicable method for 'grid.draw' applied to an object of class "list"
I can’t unlist it becasue it just turns into a long character vector. any ideas?
If it’s absolutely crucial I can spend the time to make an reproducible example but I’m more likely just missing a simple step.
Я пытаюсь сохранить сюжет с помощью ggsave(). Я ввожу следующее:
library(ggplot2)
Test = data.frame("X" = seq(1, 10, 1), "Y" = 2*seq(1, 10, 1))
P = ggplot(
Test, aes(x=X, y=Y))+
geom_line()
ggsave(P, "test.pdf", device = "pdf")
Но получаю ошибку:
Saving 7 x 7 in image
Error in UseMethod("grid.draw") :
no applicable method for 'grid.draw' applied to an object of class "character"
2 ответа
Лучший ответ
Многие функции R, сохраняющие данные, такие как write.table(), saveRDS() и т. Д., Принимают в качестве первого аргумента сохраняемый объект. Но это неверно для ggsave(). Вместо этого по умолчанию его первым аргументом является имя файла для сохранения. Таким образом, приведенный выше синтаксис необходимо изменить одним из двух способов:
ggsave(plot = P, filename = "test.pdf", device = "pdf")
ggsave("test.pdf", P, device = "pdf")
16
Michael Ohlrogge
12 Фев 2020 в 17:34
Я думаю, что это может работать даже без добавления параметра пути, оно автоматически сохранится в папке загрузок.
0
Matt the Sandcat
16 Авг 2022 в 03:56
У меня есть сюжет, сгенерированный ggplot2, который содержит две легенды. Расположение легенд не идеальное, поэтому хотелось бы их подкорректировать. Я пытался подражать методу, показанному на
ответ на вопрос «Как независимо расположить две легенды в ggplot». Пример, показанный в этом ответе, работает. Однако я не могу заставить описанный метод работать в моей ситуации.
Я использую R 2.15.3 (2013-03-01), ggplot2_0.9.3.1, решетку_0.20-13, gtable_0.1.2, gridExtra_0.9.1 на сжатии Debian.
Рассмотрим сюжет, созданный minimal.R. Это похоже на мой настоящий сюжет.
########################
minimal.R
########################
get_stat <- function()
{
n = 20
q1 = qnorm(seq(3, 17)/20, 14, 5)
q2 = qnorm(seq(1, 19)/20, 65, 10)
Stat = data.frame(value = c(q1, q2),
pvalue = c(dnorm(q1, 14, 5)/max(dnorm(q1, 14, 5)), d = dnorm(q2, 65, 10)/max(dnorm(q2, 65, 10))),
variable = c(rep('true', length(q1)), rep('data', length(q2))))
return(Stat)
}
stat_all<- function()
{
library(ggplot2)
library(gridExtra)
stathuman = get_stat()
stathuman$dataset = "human"
statmouse = get_stat()
statmouse$dataset = "mouse"
stat = merge(stathuman, statmouse, all=TRUE)
return(stat)
}
simplot <- function()
{
Stat = stat_all()
Pvalue = subset(Stat, variable=="true")
pdf(file = "CDF.pdf", width = 5.5, height = 2.7)
stat = ggplot() + stat_ecdf(data=Stat, n=1000, aes(x=value, colour = variable)) +
theme(legend.key = element_blank(), legend.background = element_blank(), legend.position=c(.9, .25), legend.title = element_text(face = "bold")) +
scale_x_continuous("Negative log likelihood") +
scale_y_continuous("Proportion $<$ x") +
facet_grid(~ dataset, scales='free') +
scale_colour_manual(values = c("blue", "red"), name="Data type",
labels=c("Gene segments", "Model"), guide=guide_legend(override.aes = list(size = 2))) +
geom_area(data=Pvalue, aes(x=value, y=pvalue, fill=variable), position="identity", alpha=0.5) +
scale_fill_manual(values = c("gray"), name="Pvalue", labels=c(""))
print(stat)
dev.off()
}
simplot()
В результате получается следующий сюжет. Как видно, Data type
и Pvalue легенды не очень хорошо позиционированы. Я изменил этот код на
minimal2.R.
В версии 1, в которой легенда должна располагаться вверху, код выполняется без ошибок, но легенда не отображается.
РЕДАКТИРОВАТЬ: отображаются два поля, одно поверх другого. Верхний пустой. Если я не установлю высоты в grid.arrange(), как предлагает @baptiste, то легенда и сюжет помещаются в нижнее поле. Если я установлю высоту, как показано, я не увижу легенду.
РЕДАКТИРОВАТЬ2: кажется, что дополнительное пустое поле было вызвано grid.newpage, который я скопировал из предыдущего вопроса. Я не уверен, почему это было там. Если я не использую эту строку, я получаю только одну коробку/страницу.
С версией 2 я получаю эту ошибку.
Error in UseMethod("grid.draw") :
no applicable method for 'grid.draw' applied to an object of class "c('gg', 'ggplot')"
Calls: simplot -> grid.draw
РЕДАКТИРОВАТЬ: если я использую print(plotNew) как предложил @baptiste, я получаю следующую ошибку
Error in if (empty(data)) { : missing value where TRUE/FALSE needed
Calls: simplot ... facet_map_layout -> facet_map_layout.grid -> locate_grid.
Я попытался выяснить, что здесь происходит, но не смог найти много соответствующей информации.
ЗАМЕТКИ:
-
Я не уверен, почему я получаю эффект лестницы для эмпирического CDF. Я уверен, этому есть очевидное объяснение. Пожалуйста, просветите меня, если вы знаете.
-
Я готов рассмотреть альтернативы этому коду и даже ggplot2 для создания этого графика, если кто-нибудь может предложить альтернативы, например, matplotlib, с которым я никогда серьезно не экспериментировал.
-
Добавление
print(ggplot_gtable(ggplot_build(stat2)))в
minimal2.Rдает мнеTableGrob (7 x 7) "layout": 12 grobs z cells name grob 1 0 (1-7,1-7) background rect[plot.background.rect.186] 2 1 (3-3,4-4) strip-top absoluteGrob[strip.absoluteGrob.135] 3 2 (3-3,6-6) strip-top absoluteGrob[strip.absoluteGrob.141] 4 5 (4-4,3-3) axis-l absoluteGrob[GRID.absoluteGrob.129] 5 3 (4-4,4-4) panel gTree[GRID.gTree.155] 6 4 (4-4,6-6) panel gTree[GRID.gTree.169] 7 6 (5-5,4-4) axis-b absoluteGrob[GRID.absoluteGrob.117] 8 7 (5-5,6-6) axis-b absoluteGrob[GRID.absoluteGrob.123] 9 8 (6-6,4-6) xlab text[axis.title.x.text.171] 10 9 (4-4,2-2) ylab text[axis.title.y.text.173] 11 10 (4-4,4-6) guide-box gtable[guide-box] 12 11 (2-2,4-6) title text[plot.title.text.184]Я не понимаю этой поломки. Кто-нибудь может объяснить? Делает
guide-boxсоответствуют легенде, а откуда это известно?
Вот модифицированная версия моего кода, minimal2.R.
########################
minimal2.R
########################
get_stat <- function()
{
n = 20
q1 = qnorm(seq(3, 17)/20, 14, 5)
q2 = qnorm(seq(1, 19)/20, 65, 10)
Stat = data.frame(value = c(q1, q2),
pvalue = c(dnorm(q1, 14, 5)/max(dnorm(q1, 14, 5)), d = dnorm(q2, 65, 10)/max(dnorm(q2, 65, 10))),
variable = c(rep('true', length(q1)), rep('data', length(q2))))
return(Stat)
}
stat_all<- function()
{
library(ggplot2)
library(gridExtra)
library(gtable)
stathuman = get_stat()
stathuman$dataset = "human"
statmouse = get_stat()
statmouse$dataset = "mouse"
stat = merge(stathuman, statmouse, all=TRUE)
return(stat)
}
simplot <- function()
{
Stat = stat_all()
Pvalue = subset(Stat, variable=="true")
pdf(file = "CDF.pdf", width = 5.5, height = 2.7)
## only include data type legend
stat1 = ggplot() + stat_ecdf(data=Stat, n=1000, aes(x=value, colour = variable)) +
theme(legend.key = element_blank(), legend.background = element_blank(), legend.position=c(.9, .25), legend.title = element_text(face = "bold")) +
scale_x_continuous("Negative log likelihood") +
scale_y_continuous("Proportion $<$ x") +
facet_grid(~ dataset, scales='free') +
scale_colour_manual(values = c("blue", "red"), name="Data type", labels=c("Gene segments", "Model"), guide=guide_legend(override.aes = list(size = 2))) +
geom_area(data=Pvalue, aes(x=value, y=pvalue, fill=variable), position="identity", alpha=0.5) +
scale_fill_manual(values = c("gray"), name="Pvalue", labels=c(""), guide=FALSE)
## Extract data type legend
dataleg <- gtable_filter(ggplot_gtable(ggplot_build(stat1)), "guide-box")
## only include pvalue legend
stat2 = ggplot() + stat_ecdf(data=Stat, n=1000, aes(x=value, colour = variable)) +
theme(legend.key = element_blank(), legend.background = element_blank(), legend.position=c(.9, .25), legend.title = element_text(face = "bold")) +
scale_x_continuous("Negative log likelihood") +
scale_y_continuous("Proportion $<$ x") +
facet_grid(~ dataset, scales='free') +
scale_colour_manual(values = c("blue", "red"), name="Data type", labels=c("Gene segments", "Model"), guide=FALSE) +
geom_area(data=Pvalue, aes(x=value, y=pvalue, fill=variable), position="identity", alpha=0.5) +
scale_fill_manual(values = c("gray"), name="Pvalue", labels=c(""))
## Extract pvalue legend
pvalleg <- gtable_filter(ggplot_gtable(ggplot_build(stat2)), "guide-box")
## no legends
stat = ggplot() + stat_ecdf(data=Stat, n=1000, aes(x=value, colour = variable)) +
theme(legend.key = element_blank(), legend.background = element_blank(), legend.position=c(.9, .25), legend.title = element_text(face = "bold")) +
scale_x_continuous("Negative log likelihood") +
scale_y_continuous("Proportion $<$ x") +
facet_grid(~ dataset, scales='free') +
scale_colour_manual(values = c("blue", "red"), name="Data type", labels=c("Gene segments", "Model"), guide=FALSE) +
geom_area(data=Pvalue, aes(x=value, y=pvalue, fill=variable), position="identity", alpha=0.5) +
scale_fill_manual(values = c("gray"), name="Pvalue", labels=c(""), guide=FALSE)
## Add data type legend: version 1 (data type legend should be on top)
## plotNew <- arrangeGrob(dataleg, stat, heights = unit.c(dataleg$height, unit(1, "npc") - dataleg$height), ncol = 1)
## Add data type legend: version 2 (data type legend should be somewhere in the interior)
## plotNew <- stat + annotation_custom(grob = dataleg, xmin = 7, xmax = 10, ymin = 0, ymax = 4)
grid.newpage()
grid.draw(plotNew)
dev.off()
}
simplot()
Согласно моему комментарию в ответе Чейз, вы можете удалить много этого материала, используя element_blank:
dat <- data.frame(x=runif(10),y=runif(10))
p <- ggplot(dat, aes(x=x, y=y)) +
geom_point() +
scale_x_continuous(expand=c(0,0)) +
scale_y_continuous(expand=c(0,0))
p + theme(axis.line=element_blank(),axis.text.x=element_blank(),
axis.text.y=element_blank(),axis.ticks=element_blank(),
axis.title.x=element_blank(),
axis.title.y=element_blank(),legend.position="none",
panel.background=element_blank(),panel.border=element_blank(),panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),plot.background=element_blank())
Похоже, что все еще есть небольшой запас по краю полученного .png, когда я его сохраняю. Возможно, кто-то еще знает, как удалить этот компонент.
(Историческое примечание: поскольку ggplot2 версия 0.9.2, opts устарела. Вместо этого используйте theme() и замените theme_blank() на element_blank().)

