Включение изображений на метку оси в анимированном ggplot2 - PullRequest
0 голосов
/ 03 марта 2019

Я создал анимированную линейку, отображающую цели, забитые игроками (вымышленные).

См. Воспроизведенные данные для примера:

df <- data.frame(Player = rep(c("Aguero", "Salah", "Aubameyang", "Kane"), 6),
                 Team = rep(c("ManCity", "Liverpool", "Arsenal", "Tottenham"), 6), 
                 Gameday = c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6),
                 Goals = c(0,1,2,0,1,1,3,1,2,1,3,2,2,2,4,3,3,2,4,5,5,3,5,6),
                 stringsAsFactors = F)

Следующие анимированные гистограммы создаются с помощью кода ниже.

enter image description here

# loading required
library(tidyverse)
library(gganimate)
library(png)

Отредактировано: Я хотел бы включить следующие значки для каждого игрока:

icon1.png <- image_read('https://raw.githubusercontent.com/sialbi/examples/master/player1.png')
icon2.png <- image_read('https://raw.githubusercontent.com/sialbi/examples/master/player2.png')
icon3.png <- image_read('https://raw.githubusercontent.com/sialbi/examples/master/player3.png')
icon4.png <- image_read('https://raw.githubusercontent.com/sialbi/examples/master/player4.png')

gap <- df %>%
  group_by(Gameday) %>%
  mutate(rank = min_rank(-Goals) * 1,
         Value_rel = Goals/Goals[rank==1],
         Value_lbl = paste0(" ", Goals)) %>%
  filter(rank <=10) %>%
  ungroup()

gap %>%
  group_by(Player) %>%
  arrange(Gameday) %>%
  mutate(prev.rank = lag(rank)) %>%
  ungroup() %>%

  group_by(Gameday) %>%
  arrange(rank, prev.rank) %>%
  mutate(x = seq(1, n())) %>%
  ungroup() %>%

  ggplot(aes(x = x, y = Goals, fill = Player, color = Player)) +
  geom_col() +
  geom_text(aes(y = 0, label = Player), size = 5, color="black", hjust = -0.05) +
  geom_text(aes(label = Value_lbl), hjust = 0) +
  coord_flip(clip = "off", expand = FALSE) +
  scale_y_continuous(labels = scales::comma) +
  scale_x_reverse() +
  guides(color = FALSE, fill = FALSE) +
  labs(title = "Gameday: {closest_state}", x="", y = "Goals scored") +
  theme(plot.title = element_text(hjust = 0, size = 26),
        axis.ticks.y = element_blank(), 
        axis.text.y  = element_blank(),
        plot.margin = margin(1,1,1,4, "cm")) +
 transition_states(Gameday, transition_length = 4, state_length = 1) +
 ease_aes('cubic-in-out')

Задача

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

Изображения (круги) также должны перемещаться вверх и вниз как столбцы.

IsЕсть ли способ включить изображения по оси Y?

enter image description here

Отредактированный код

После представленных предложений я смог исправитьпроблемы.Код ниже работает соответственно.

library(imager)
library(ggimage)
library(magick)
library(tidyverse)
library(gganimate)
library(png)
library(gapminder)


 #read data
 df <- data.frame(Player = rep(c("Aguero", "Salah", "Aubameyang", "Kane"), 6),
             Team = rep(c("ManCity", "Liverpool", "Arsenal", "Tottenham"), 6), 
             Gameday = c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6),
             Goals = c(0,1,2,0,1,1,3,1,2,1,3,2,2,2,4,3,3,2,4,5,5,3,5,6),
             stringsAsFactors = F)

# import images
df2 <- data.frame(Player = c("Aguero", "Salah", "Aubameyang", "Kane"),
              Image = sample(c("https://raw.githubusercontent.com/sialbi/examples/master/player1.png",
                        "https://raw.githubusercontent.com/sialbi/examples/master/player2.png",
                        "https://raw.githubusercontent.com/sialbi/examples/master/player3.png",
                        "https://raw.githubusercontent.com/sialbi/examples/master/player4.png")),
              stringsAsFactors = F)


gap <- df %>%
  group_by(Gameday) %>%
  mutate(rank = min_rank(-Goals) * 1,
         Value_rel = Goals/Goals[rank==1],
         Value_lbl = paste0(" ", Goals)) %>%
  filter(rank <=10) %>%
  ungroup()

p = gap %>%
  left_join(df2, by = "Player") %>% # add image file location to the dataframe being
  group_by(Player) %>%
  arrange(Gameday) %>%
  mutate(prev.rank = lag(rank)) %>%
  ungroup() %>%      
  group_by(Gameday) %>%
  arrange(rank, prev.rank) %>%
  mutate(x = seq(1, n())) %>%
  ungroup()

ggplot(p, aes(x = x, y = Goals, fill = Player, color = Player)) +
  geom_col() +
  geom_text(aes(y = 0, label = Player), size = 5, color="black", hjust = -0.05) +
  geom_text(aes(label = Value_lbl), hjust = 0) +

  # where the error occurs 
  geom_image(aes(x = x, Image = Image), y = 0,  
             size = 0.25, hjust = 1,
             inherit.aes = FALSE) +

  coord_flip(clip = "off", expand = FALSE) +
  scale_y_continuous(labels = scales::comma) +
  scale_x_reverse() +
  guides(color = FALSE, fill = FALSE) +
  labs(title = "Gameday: {closest_state}", x = "", y = "Goals scored") +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0, size = 26),
        axis.ticks.y = element_blank(),
        axis.text.y  = element_blank(),
        plot.margin = margin(1, 1, 1, 4, "cm")) +
  transition_states(Gameday, transition_length = 4, state_length = 1) +
  ease_aes('cubic-in-out')

enter image description here

1 Ответ

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

Вы можете попробовать следующее:

Шаг 0. Создание изображений в формате png для использования, поскольку я не хочу беспокоиться о нарушениях авторских прав.

emoji.list <- c("grinning", "smile", "heart_eyes", "smirk")
for(i in seq_along(emoji.list)) {
  ggsave(paste0("icon", i, ".png"),
         ggplot() + 
           emojifont::geom_emoji(alias = emoji.list[i], size = 10, vjust = 0.5) +
           theme_void(),
         width = 0.4, height = 0.4, units = "in")
}
rm(emoji.list, i)

Шаг 1. Создайте фрейм данных, отображающий каждого игрока в местоположение его файла изображения.

df2 <- data.frame(Player = c("Aguero", "Salah", "Aubameyang", "Kane"),
                  Image = c("icon1.png", "icon2.png", "icon3.png", "icon4.png"),
                  stringsAsFactors = F)

Шаг 2. Добавьте изображение к графику вновый geom_image слой и анимируйте все как раньше.

library(ggimage)

gap %>%
  left_join(df2, by = "Player") %>% # add image file location to the dataframe being
                                    # passed to ggplot()      
  group_by(Player) %>%
  arrange(Gameday) %>%
  mutate(prev.rank = lag(rank)) %>%
  ungroup() %>%      
  group_by(Gameday) %>%
  arrange(rank, prev.rank) %>%
  mutate(x = seq(1, n())) %>%
  ungroup() %>%

  ggplot(aes(x = x, y = Goals, fill = Player, color = Player)) +
  geom_col() +
  geom_text(aes(y = 0, label = Player), size = 5, color="black", hjust = -0.05) +
  geom_text(aes(label = Value_lbl), hjust = 0) +

  geom_image(aes(x = x, image = Image), y = 0,  # add geom_image layer
             size = 0.25, hjust = 1,
             inherit.aes = FALSE) +

  coord_flip(clip = "off", expand = FALSE) +
  scale_y_continuous(labels = scales::comma) +
  scale_x_reverse() +
  guides(color = FALSE, fill = FALSE) +
  labs(title = "Gameday: {closest_state}", x = "", y = "Goals scored") +
  theme_classic() +
  theme(plot.title = element_text(hjust = 0, size = 26),
        axis.ticks.y = element_blank(),
        axis.text.y  = element_blank(),
        plot.margin = margin(1, 1, 1, 4, "cm")) +
  transition_states(Gameday, transition_length = 4, state_length = 1) +
  ease_aes('cubic-in-out')

animated plot

...