在动画ggplot2中的轴标签上包含图像 [英] Including images on axis label in an animated ggplot2

查看:57
本文介绍了在动画ggplot2中的轴标签上包含图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个动画的条形图,显示了玩家得分的得分(虚构).

I created an animated bar plot displaying goals scored by players (fictional).

请参见示例的复制数据:

Please see the reproduced data for the example:

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)

下面的动画条形图由下面的代码创建.

Following animated bar plot are created by the code below.

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

我想为每个玩家添加以下图标:

Edited: I would like to include following icons for each player:

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')

问题

要完成动画,我想在y轴上包含每个玩家的图片.在下面,我编辑了动画以显示所需的结果(选择圆圈是为了避免侵犯任何版权).

To complete the animation I would like to include a picture of each player on the y axis. Below I edited the animation to display the desired result (the circles were chosen to avoid violating any copyrights).

图像(圆圈)也应随着条形而上下移动.

The images (circles) should also move up and down as the bars.

是否可以在y轴上包含图像?

Is there are way to include images on the y-axis?

提出建议后,我得以解决问题.下面的代码可以正常工作.

After the presented suggestions I was able to fix the problems. The code below is working accordingly.

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')

推荐答案

您可以尝试以下操作:

第0步.创建png图片供使用,因为我也不想担心侵犯版权的情况.

Step 0. Create png images for use, because I don't want to worry about copyright violations either.

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步.创建一个将每个玩家映射到其图像文件位置的数据框.

Step 1. Create a data frame mapping each player to the location of his image file.

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

第2步.将图像添加到新的geom_image图层中,像以前一样为所有东西设置动画.

Step 2. Add image to plot in a new geom_image layer, & animate everything as before.

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')

这篇关于在动画ggplot2中的轴标签上包含图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆