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

Я хочу автоматически перенаправить все графики в файл (причина: см. ниже). Есть ли не-хакерский способ сделать это?

Не имея этого, я на самом деле не боюсь переопределять встроенные функции, я это в отчаянии. Самый простой способ, который я могу придумать, - это подключиться к основной функции создания окна графика и вызвать pdf(…), а затем подключиться к функции завершения графика и вызвать там dev.off().

Но что это за функции? С помощью отладки я предварительно определил dev.hold и dev.flush, но действительно ли это верно для всех? Могу ли я подключиться к этим функциям? Я не могу переопределить их с помощью R.utilsreassignInNamespace, потому что они заблокированы, и простое помещение одноименных функций в глобальное пространство имен не работает (их игнорирует plot).


Итак, зачем мне делать что-то настолько ужасное?

Поскольку я работаю на удаленном сервере, и, несмотря на все мои попытки и длительные сеансы отладки с поддержкой наших систем, я не могу заставить пересылку X11 работать надежно. Отсутствие возможности предварительного просмотра сюжета делает мой рабочий процесс ужасно неэффективным. Я отказался от попыток заставить X11 работать, поэтому теперь я создаю PDF-файлы в своей папке public_html и просто обновляю браузер.

Это работает довольно хорошо, за исключением того, что очень раздражает и требует много времени, чтобы всегда окружать вызовы функций построения графика pdf(…) … dev.off(), особенно в интерактивных сеансах, когда вы хотите быстро создать график во время встречи с соавторами. На самом деле, это очень раздражает, и у них (по понятным причинам) не хватает на это терпения.

Сейчас я помогаю себе со следующим определением функции:

preview <- function (.expr, ...) {
    on.exit(dev.off())
    pdf(PREVIEW_FILE_NAME, ...)
    eval(substitute(.expr))
}

Который используется так:

preview(plot(1:100, rnorm(100) * 1:100))

Это работает - хорошо. Но этот рабочий процесс является настоящим узким местом на собраниях, и я хотел бы избавиться от вызова preview, чтобы максимально упростить его.

Есть шанс вообще?


person Konrad Rudolph    schedule 12.07.2013    source источник
comment
Раньше у меня тоже была эта проблема, я пробовал переадресацию X11, и она была медленной и неуклюжей. Я также попытался сбросить все свои файлы в pdf, используя ваш шаблон. Но потом я перешел на RStudio Server, и все эти проблемы ушли. Я мог быстро просмотреть свои графики локально, которые были рассчитаны на сервере. Просто предложение.   -  person nograpes    schedule 12.07.2013
comment
Действительно ли функция preview стоит вам измеримого времени? То есть, если вы запускаете его локально, это стоит. Я ожидал, что большую часть времени будет занимать запись и чтение удаленного файла. Я также ожидаю, что размещение хуков внутри plot будет не быстрее, чем ваша функция preview. Кстати, я не думаю, что у вас есть возможность использовать какой-либо другой оконный сервер, кроме X11, или просто запускать приложение для удаленного рабочего стола? (или см. хорошее предложение @nograpes)   -  person Carl Witthoft    schedule 12.07.2013
comment
@Carl Накладные расходы связаны с добавленным вводом текста, а не со временем выполнения. И да, это влияние.   -  person Konrad Rudolph    schedule 12.07.2013
comment
Ладно, я что-то неправильно понимаю. Ввод preview(plot(x[1:35],y[31:65],t='l',col=rainbow(40),xlab="wtf", ylab='fubar',main='this is a lot of typing') занимает заметно больше времени, чем ввод только строки plot? Что-то не так, и не в последнюю очередь: если у вас есть соавторы, значит, вы занимаетесь разработкой, а не презентацией, верно? Таким образом, им вряд ли стоит ждать порядка нескольких секунд, чтобы увидеть, как пишется и строится новый алгоритм. Так что же происходит на самом деле?   -  person Carl Witthoft    schedule 12.07.2013
comment
Почему не Plot <- function(...) {on.exit(dev.off()); pdf(file="foo.pdf"); plot(...)}?   -  person Joshua Ulrich    schedule 12.07.2013
comment
Интересно, может ли здесь пригодиться какой-то javascript-график в браузере? rcharts.io кажется многообещающим   -  person baptiste    schedule 12.07.2013
comment
@Carl Плохая формулировка. Две причины. Во-первых, как уже упоминалось, узкое место. Дело не в том, что ввод preview() занимает много времени, но если вы находитесь на совещании и хотите попробовать вывести данные на график по-новому, введите в консоли останавливает разговор. Это неудобно и раздражает. И поэтому вы печатаете быстро. И делать ошибки. И это занимает больше времени. И это становится более раздражающим. Кстати, это касается не только меня, я видел это и у других. Итог: безобидный маленький preview() вреден.   -  person Konrad Rudolph    schedule 12.07.2013
comment
@Carl Часть вторая, и я действительно забыл об этом в вопросе: становится хуже. Когда я работаю один, я фактически использую плагин Vim, похожий на ESS, который вставляет код из скрипта в R. Очевидно, что это абсолютно не работает с моим preview подходом, поскольку, очевидно, внутри скрипта я не использую preview, я (явно, через pdf(…)…dev.off()) рисую в какой-то другой выходной файл. Так что мне действительно нужно иметь возможность просто вставить функцию построения графика и получить эту работу.   -  person Konrad Rudolph    schedule 12.07.2013
comment
@JoshuaUlrich Потому что это только работает с plot, а не с множеством других функций построения графиков, верно?   -  person Konrad Rudolph    schedule 12.07.2013
comment
Если печатание останавливает разговор, то же самое можно сказать и о любом другом методе создания сюжета. Возможно, вам нужно перейти на графический интерфейс TclTK с ползунками для масштабирования, кнопками для линий и точек, выпадающими меню для источников данных. Со всем уважением, я не убежден, что ваша проблема — это то, о чем вы думаете, и что реорганизация протоколов собраний окажется более плодотворной.   -  person Carl Witthoft    schedule 12.07.2013
comment
@Carl Жаль (как «ничего не печатать» не звучит быстрее?). Так что давайте просто проигнорируем это и сосредоточимся на другом варианте использования — вставке команд из внешнего редактора.   -  person Konrad Rudolph    schedule 13.07.2013
comment
Можно ли легко возиться с плагином Vim? Если это так, вы можете настроить его команду вставки в R, чтобы она добавляла к каждому посланию вызов чего-то вроде closeall(), где closall <- function() dummy<-capture.output(replicate(length(dev.list()), dev.off())). (Это предполагает, что вы также приняли предложение Грега Сноу установить options(device="pdf").)   -  person Josh O'Brien    schedule 13.07.2013


Ответы (1)


Если вы установите options(device=FUN), то функция графического устройства FUN станет новым графическим устройством по умолчанию, которое будет открыто при создании графика, а устройство еще не открыто.

Таким образом, одним из вариантов было бы написать функцию, которая вызывает pdf или png или другое графическое устройство с нужным именем файла и параметрами (вероятно, onefile=FALSE в pdf), а затем установить эту функцию по умолчанию в параметрах. Возможно, вам придется использовать один из dev.off, plot.new или frame, чтобы завершить текущий график (R не финализируется, пока вы не закроете устройство или не перейдете к новому графику, если вы хотите что-то добавить к текущему графику).

Если вы никогда не будете добавлять на график, вы можете использовать addTaskCallback для автоматического вызова dev.off для вас. Могут быть и другие хуки, которые вы могли бы использовать для финализации.

person Greg Snow    schedule 12.07.2013
comment
В частности, сделайте options(device="pdf"). Как говорит Грег, вам нужно будет сделать dev.off() (или его более короткий псевдоним), чтобы завершить график, но это кажется лучше, чем ожидать, что R узнает, когда вы закончили добавлять слои к графику (с points(), lines(), legend() , так далее.) - person Josh O'Brien; 12.07.2013