Как повернуть пользовательскую аннотацию в ggplot? - PullRequest
0 голосов
/ 15 февраля 2019

Я хотел бы повернуть изображение, включенное в annotation_custom в ggplot2.

Для анимации с gganimate я хотел бы добавить изображения с определенными углами к линейному графику.К сожалению, в annotation_custom.

library(tidyverse)
library(grid)
library(png)

gundf <- tibble(year = c(1999:2017),
                deaths = c(28874, 28663, 29573, 30242, 30136, 29569, 30694, 30896, 
                           31224, 31593, 31347, 31672, 32351, 33563, 33636, 33594, 
                           36252, 38658, 39773))

# Download png from cl.ly/47216db435d3
bullet <- rasterGrob(readPNG("bullet.png"))

gundf %>% 
  ggplot(aes(x=year, y=deaths)) + 
  geom_line(size=1.2) +
  mapply(function(x, y) {
    annotation_custom(bullet, xmin = x-0.5, 
                              xmax = x+0.5, 
                              ymin = y-500, 
                              ymax = y+500)
                         },
    gundf$year, gundf$deaths) + 
  theme_minimal()

нет параметра angle Результат:

image from cl.ly/b83aefc7a7fa/gunplot.png

Как виднона графике все пули выровнены по горизонтали.Я хотел бы повернуть пули, чтобы соответствовать наклону линии.В анимации линия должна выглядеть так, как будто стреляет пуля (что будет другой проблемой, поскольку в annotate_custom нет параметров aes).

Заранее спасибо за ваши предложения!

1 Ответ

0 голосов
/ 19 марта 2019

Вы можете использовать пакет magick для вращения файла png:

library(magick)

bullet <- magick::image_read("bullet.png")

## To remove white borders from the example png
bullet <- magick::image_background(bullet, "#FF000000")

## Create angle column
gundf$angle <- seq(0,360, length.out = nrow(gundf))

## Plot
gundf %>% 
  ggplot(aes(x=year, y=deaths)) + 
  geom_line(size=1.2) +
  mapply(function(x, y, angle) {
    annotation_custom(rasterGrob(magick::image_rotate(bullet, angle)),
                              xmin = x-0.5, 
                              xmax = x+0.5, 
                              ymin = y-500, 
                              ymax = y+500)
                         },
    gundf$year, gundf$deaths, gundf$angle) + 
  theme_minimal()

enter image description here

Что касается вашего вопроса очтобы сделать пулю для следования линии, см. комментарии к этому ответу .Сделать объекты с таким же наклоном, что и у линии в ggplot2, довольно сложно, потому что вам нужно знать соотношение сторон области черчения (насколько мне известно, информацию, которая нигде не печатается в данный момент).Вы можете решить эту проблему, превратив свой график в файл (pdf или png), используя определенное соотношение сторон.Затем вы можете использовать уравнение @Andrie (180/pi * atan(slope * aspect ratio)) вместо того, которое я использовал в примере.Там может быть небольшое несоответствие, которое вы можете попытаться скорректировать с помощью константы.Кроме того, было бы неплохо линейно интерполировать одну точку между каждой точкой в ​​вашем наборе данных, потому что теперь вы строите график с изменением наклона.Делать это в анимации будет плохо.Вероятно, было бы легче построить пулю там, где наклон постоянен.

...