Считывание в координатах пути / полигона SVG - PullRequest
2 голосов
/ 13 июля 2020

Я пытаюсь импортировать координаты пути в файле SVG, созданном с помощью Illustrator, в R.

Я подумал, что могу прочитать SVG в R с помощью grImport2, который теоретически должен импортировать Файлы SVG, но я думаю, что они могут обрабатывать только файлы SVG, созданные устройством Cairo.

Допустим, я хочу импортировать следующий файл .svg:

Here is my attempt at loading an SVG file. If I read the content correctly, it should just contain 1 (complicated) path. The warning is the same one I get when loading my SVG file created by Adobe Illustrator. Be warned that the code below will get stuck for some time!

file <- "https://upload.wikimedia.org/wikipedia/commons/d/db/Brain_Drawing.svg"
download.file(file, tmp <- tempfile(fileext = ".svg"))

# Don't run the following line, it will get your R session stuck!
x <- grImport2::readPicture(tmp)
#> Warning message:
#> In checkValidSVG(doc, warn = warn) :
#>   This picture was not generated by Cairo graphics; errors may result

unlink(tmp)

Мой идеальный результат - это data.frame с как минимум x и y координатами (якорных) точек и, возможно, некоторыми метаданными, которые могут различать разные пути. Мне не нужны интерполированные кривые и дуги или что-то в этом роде.

Есть ли какие-нибудь другие пакеты, о которых я не знаю, которые могут импортировать это? Есть ли способ преобразовать SVG в тот, который я могу прочитать в R?

1 Ответ

1 голос
/ 14 июля 2020

Хороший вопрос, Teunbrand - спасибо за сообщение. Проблема, похоже, заключается в том, чтобы grImport2 читал не-Cairo svg. Так что на самом деле нам просто нужен еще один шаг перевода: используйте пакет rsvg для чтения в SVG, отличном от Cairo, и напишите то же самое в Cairo. Как ни странно, для этого у него есть функция под названием rsvg_svg. Таким образом, мы можем прочитать удаленный файл как объект Picture в одной строке, даже не создавая локальный tmp-файл:

file <- "https://upload.wikimedia.org/wikipedia/commons/d/db/Brain_Drawing.svg"
svg  <- grImport2::readPicture(rawToChar(rsvg::rsvg_svg(file)))

К сожалению, Picture - это глубоко перечисленный объект S4, который сложнее ориентироваться, чем дерево гроба. Я уверен, что человек вашего калибра мог бы заставить его создать фрейм данных, но это нетривиально, и я не буду пытаться это здесь. По крайней мере, сами компоненты выглядят достаточно легко для сбора:

svg@content[[1]]@content[[1]]@d@segments[[3]]

#> An object of class "PathCurveTo"
#> Slot "x":
#>  [1]  791.8359 789.5286 787.1382 784.6293 782.0041 779.2962 776.5600 773.8555 771.2318 
#>   [10] 768.712 766.2875 764.8359
#> 
#> Slot "y":
#>   [1] 8.191406 8.209760 8.239691 8.282891 8.340521 8.412835 8.499026 8.597442 8.706126 
#>  [10] 8.82357  8.949580 9.031250

В любом случае, есть несколько хороших служебных функций, которые позволяют делать такие классные вещи, как это:

brainGrob <- grImport2::pictureGrob(svg)
ggplot2::ggplot() + ggplot2::geom_point(ggplot2::aes(1, 1))
grid::grid.draw(brainGrob)

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

Раньше я не видел произвольного SVG, нарисованного в сетке, поэтому был рад найти его, вызванный вашим вопросом. Еще раз спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...