Проблемы с использованием grid.edit() в Rscript

У меня проблемы с использованием grid.edit() из Rscript. Я использую grid.edit(), чтобы увеличить толщину полых точек в легенде и на диаграмме. Я взял это из этого сообщения (Изменить толщину маркера в ggplot2 ). Просто выглядит лучше ИМО. Я знаю, что из исходных файлов и Rscripts вы можете получить ggplot объектов для построения с помощью print(p), но мне нужно использовать grid.edit(), поэтому я не знаю, как это исправить. Рабочий пример ниже.

Мой R-скрипт под названием test.r

library(ggplot2)
library(grid)
library(gtable)

p <- ggplot(mtcars, aes(wt, mpg)) + geom_point(aes(shape = factor(cyl))) + scale_shape(solid = FALSE)
lwd = 2   # Set line width
g = ggplotGrob(p); dev.off()  # Get the plot grob
# Get the indices for the legend: t = top, r = right, ...
indices <- c(subset(g$layout, name == "guide-box", select = t:r))
# Get the row number of the legend in the layout
rn <- which(g$layout$name == "guide-box")
# Extract the legend
legend <- g$grobs[[rn]]
# Get the legend keys
pointGrobs = which(grepl("points", legend$grobs[[1]]$grobs))
# Check them out - no line width set
# for (i in pointGrobs) str(legend$grobs[[1]]$grobs[[i]])
# Set line width
for (n in pointGrobs) legend$grobs[[1]]$grobs[[n]]$gp$lwd = lwd
# Check them out - line width set
# for (i in pointGrobs) str(legend$grobs[[1]]$grobs[[i]])
# Put the modified legend back into the plot grob
g$layout$clip[g$layout$name == "panel"] <- "off"
g = gtable_add_grob(g, legend, t=indices$t, l=indices$l)
###g$grobs[[4]]$children[[2]]$gp$lwd = gpar(lwd = lwd)  # Alternative for setting lwd for points in the plot
grid.newpage()
grid.draw(g)
grid.edit("geom_point.points", grep = TRUE, gp = gpar(lwd = lwd))

dev.print(cairo_pdf,filename="Aplot.pdf",
 width=11, 
height=8.5)

Мой командный файл.

...\R-3.2.3\bin\x64\Rscript.exe test.r
PAUSE

Скрипт запускается, и я получаю следующую ошибку.

Error in editDLfromGPath(gPath,specs,strict,grep,global,redraw):
    'gPath' (geom_point.points) not found
Calls: grid.edit -> editDLfromGPath
Execution halted

Кроме того, PDF-файл печатается в моем рабочем каталоге с именем Rplots. Этот график имеет размер по умолчанию, и, что интересно, точки в легенде толстые, а точки на графике — нет. Похоже, что сценарий терпит неудачу в grid.edit(), но grid.draw() завершается успешно.


person CCurtis    schedule 11.03.2016    source источник
comment
Я создал Rscript для пакетной обработки данных и создания набора графиков. Я хочу распространить это среди других людей в моем офисе, которые не знают R. Любой, у кого есть подключение к сетевому диску, может запустить сценарий со своего локального компьютера, и сценарий будет обрабатывать файлы в каталоге пакетных файлов. Могу ли я использовать Rterm и создать Rprofile, который запускал бы команды напрямую или использовал source() в начале сеанса R, чтобы получить тот же результат, или использование source() приведет к тем же проблемам?   -  person CCurtis    schedule 12.03.2016
comment
Попробуйте следующее: добавьте grid.force() непосредственно перед строкой grid.edit(..... grid.force() делает grobs видимыми для функций редактирования сетки. Без grid.force() функции редактирования видят только один гроб.   -  person Sandy Muspratt    schedule 12.03.2016
comment
Он избавился от ошибки, но результат тот же. Не похоже, что grid.edit выполняет свою работу. Спасибо, полезно знать. Думаю, я мог бы попробовать создать блестящее приложение.   -  person CCurtis    schedule 13.03.2016
comment
Меня устраивает. Я использую ggplot2 v2.1.0 и gtable v0.2.0.   -  person Sandy Muspratt    schedule 13.03.2016
comment
Я опубликую ответ.   -  person Sandy Muspratt    schedule 13.03.2016


Ответы (1)


Вам нужно grid.force() график, чтобы функции редактирования сетки могли видеть все гробы. Я увеличил размер точки и множитель ширины линии, чтобы было очевидно, что редактирование вступило в силу.

library(ggplot2)
library(grid)
library(gtable)

p <- ggplot(mtcars, aes(wt, mpg)) + geom_point(aes(shape = factor(cyl)), size = 5) + scale_shape(solid = FALSE)
lwd = 3   # Set line width
g = ggplotGrob(p); dev.off()  # Get the plot grob
# Get the indices for the legend: t = top, r = right, ...
indices <- c(subset(g$layout, name == "guide-box", select = t:r))
# Get the row number of the legend in the layout
rn <- which(g$layout$name == "guide-box")
# Extract the legend
legend <- g$grobs[[rn]]
# Get the legend keys
pointGrobs = which(grepl("points", legend$grobs[[1]]$grobs))
# Check them out - no line width set
# for (i in pointGrobs) str(legend$grobs[[1]]$grobs[[i]])
# Set line width
for (n in pointGrobs) legend$grobs[[1]]$grobs[[n]]$gp$lwd = lwd
# Check them out - line width set
# for (i in pointGrobs) str(legend$grobs[[1]]$grobs[[i]])
# Put the modified legend back into the plot grob
g$layout$clip[g$layout$name == "panel"] <- "off"
g = gtable_add_grob(g, legend, t=indices$t, l=indices$l)
###g$grobs[[4]]$children[[2]]$gp$lwd = gpar(lwd = lwd)  # Alternative for setting lwd for points in the plot
grid.newpage()
grid.draw(g)

grid.ls()
grid.ls(grid.force())  # Note the difference here

grid.force()
grid.edit("geom_point.points", grep = TRUE, gp = gpar(lwd = lwd))


# Or to edit the grob (rather than edit on screen)
g = editGrob(grid.force(g), "geom_point.points", grep = TRUE, gp = gpar(lwd = lwd))
grid.newpage()
grid.draw(g)

# To give it a print method
print.ggplotgrob <- function(x) {
   grid.newpage()   
   grid.draw(x)
}
class(g) = c("ggplotgrob", class(g)) 

g

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

Моя информация о сеансе ()

R version 3.2.3 (2015-12-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

locale:
[1] LC_COLLATE=English_Australia.1252  LC_CTYPE=English_Australia.1252   
[3] LC_MONETARY=English_Australia.1252 LC_NUMERIC=C                      
[5] LC_TIME=English_Australia.1252    

attached base packages:
[1] grid      stats     graphics  grDevices utils     datasets  methods  
[8] base     

other attached packages:
[1] Cairo_1.5-9   gtable_0.2.0  ggplot2_2.1.0

loaded via a namespace (and not attached):
[1] labeling_0.3     colorspace_1.2-6 scales_0.4.0     plyr_1.8.3      
[5] tools_3.2.3      Rcpp_0.12.3      digest_0.6.9     munsell_0.4.3
person Sandy Muspratt    schedule 13.03.2016
comment
Успешно справился! Думаю, я рано сдался. Работает отлично. По какой-то причине однажды я применил это к своим реальным графикам, предоставив метод печати, который не работал, и было необходимо использовать grid.newpage и `grid.draw, но здесь нет никаких претензий. Очень рад, что это работает. Большое спасибо. - person CCurtis; 15.03.2016
comment
Это может быть связано с версией ggplot2. Метод печати не будет работать со старыми версиями. - person Sandy Muspratt; 15.03.2016
comment
Да, прошло несколько месяцев с тех пор, как я обновился. Придется делать обновление, я думаю. - person CCurtis; 15.03.2016