Need help improving this GIF appearance while it r

2019-12-16 20:03发布

问题:

I'm trying to run a GIF inside my shiny App. I'm technically using this code to generate a GIF and upload it manually from my computer inside the APP. Part of my dataset is shown below, what I'm trying to do is run a GIF that shows the top 10 movies from 1960 - 2015.

this is the link to my GIF. https://media.giphy.com/media/U4eSLRaDbGpjqU0V42/giphy.gif

This is my a picture of my App - (https://imgur.com/3Ddao5S) I need to address 4 problems.

1 - First when I run this on my Shiny tab the movie names some of them are well cut out, you can't few them fully. How do I fix its orientation?

2 - I want the revenue at the end shown like 1M or 3M or 300M NOT 2554489 and definitely NOT like 1e+ 554 etc Is there a way to set the X axis like that?

3 - The gridlines are ugly AF how do I remove them?

4 - Slow it down, HOW?

Yes, I know my App is not directly rendering the GIF, I spent weeks couldn't do it GIF created inside just doesn't work.

ui <- fluidPage(theme = shinytheme("cerulean"),
                titlePanel(p(strong("Movie browser, 1960 - 2014", windowTitle = "Movies"))),   

                # Sidebar layout with a input and output definitions
                sidebarLayout(
mainPanel(
                    tabsetPanel(
                     tabPanel(h4(p(strong("GIF"))), tags$img(src = "outfile.GIF"))                  
                  )
                )
)

structure(list(id = c(135397L, 135397L, 76341L, 76341L, 262500L, 
140607L, 140607L, 140607L, 168259L, 168259L), budget = c(150000000L, 
150000000L, 150000000L, 150000000L, 110000000L, 200000000L, 200000000L, 
200000000L, 190000000L, 190000000L), revenue = c(1513528810, 
1513528810, 378436354, 378436354, 295238201, 2068178225, 2068178225, 
2068178225, 1506249360, 1506249360), title = structure(c(3L, 
3L, 4L, 4L, 2L, 5L, 5L, 5L, 1L, 1L), .Label = c("Furious 7", 
"Insurgent", "Jurassic World", "Mad Max: Fury Road", "Star Wars: The Force Awakens"
), class = "factor"), homepage = structure(c(2L, 2L, 3L, 3L, 
5L, 4L, 4L, 4L, 1L, 1L), .Label = c("http://www.furious7.com/", 
"http://www.jurassicworld.com/", "http://www.madmaxmovie.com/", 
"http://www.starwars.com/films/star-wars-episode-vii", "http://www.thedivergentseries.movie/#insurgent"
), class = "factor"), director = structure(c(1L, 1L, 2L, 2L, 
5L, 3L, 3L, 3L, 4L, 4L), .Label = c("Colin Trevorrow", "George Miller", 
"J.J. Abrams", "James Wan", "Robert Schwentke"), class = "factor"), 
    runtime = c(124L, 124L, 120L, 120L, 119L, 136L, 136L, 136L, 
    137L, 137L), vote_average = c(6.5, 6.5, 7.1, 7.1, 6.3, 7.5, 
    7.5, 7.5, 7.3, 7.3), release_year = c(2015L, 2015L, 2015L, 
    2015L, 2015L, 2015L, 2015L, 2015L, 2015L, 2015L), genre = structure(c(1L, 
    2L, 1L, 2L, 2L, 1L, 2L, 4L, 1L, 3L), .Label = c("Action", 
    "Adventure", "Crime", "Fantasy"), class = "factor"), breakeven = c(1363528810, 
    1363528810, 228436354, 228436354, 185238201, 1868178225, 
    1868178225, 1868178225, 1316249360, 1316249360), AerageVotesCat = structure(c(2L, 
    2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L), .Label = c("Excellent", 
    "Good"), class = "factor")), row.names = c(NA, 10L), class = "data.frame")
UI:
# library(gifski)
library(ggplot2)
library(gganimate)
library(dplyr)
library(scales)
library(shiny)



  output$plot2 <- renderImage({
    df2 <- df1 %>%
      group_by(release_year) %>%
      # The * 1 makes it possible to have non-integer ranks while sliding
      mutate(rank = rank(-revenue),
             Value_rel = revenue/revenue[rank==1],
             Value_lbl = paste0(" ",round(revenue))) %>%
      group_by(title) %>% 
      filter(rank <=10) %>%
      ungroup()
    staticplot = ggplot(df2, aes(rank, group = title, 
                                           fill = as.factor(title), color = as.factor(title))) +
      geom_tile(aes(y = revenue/2,
                    height = revenue,
                    width = 0.9), alpha = 0.8, color = NA) +
      geom_text(aes(y = 0, label = paste(title, " ")), vjust = 0.2, hjust = 1) +
      geom_text(aes(y=revenue,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) +
      theme(axis.line=element_blank(),
            axis.text.x=element_blank(),
            axis.text.y=element_blank(),
            axis.ticks=element_blank(),
            axis.title.x=element_blank(),
            axis.title.y=element_blank(),
            legend.position="none",
            panel.background=element_blank(),
            panel.border=element_blank(),
            panel.grid.major=element_blank(),
            panel.grid.minor=element_blank(),
            panel.grid.major.x = element_line( size=.1, color="grey" ),
            panel.grid.minor.x = element_line( size=.1, color="grey" ),
            plot.title=element_text(size=25, hjust=0.5, face="bold", colour="grey", vjust=-1),
            plot.subtitle=element_text(size=18, hjust=0.5, face="italic", color="grey"),
            plot.caption =element_text(size=8, hjust=0.5, face="italic", color="grey"),
            plot.background=element_blank(),
            plot.margin = margin(2,2, 2, 4, "cm"))

    anim = staticplot + transition_states(release_year, transition_length = 4, state_length = 1) +
      view_follow(fixed_x = TRUE)  +
      labs(title = 'Revenue ($) per Year for the top 10 movies : {closest_state}',  
           subtitle  =  "Top 10 Movies",
           caption  = "Revenue in USD | Data Source: Kaggle")
    anim_save("outfile.gif",animate(anim, 200, fps = 4,  width = 800, height = 900))
  })

    }
  )

}


# Create the Shiny app object
shinyApp(ui = ui, server = server)

回答1:

I do not know answers to all of your questions, but please have a look at the self-sustainable code below:

library(ggplot2)
library(reshape2)
library(scales)

example_df <- data.frame(movie=c("A", "B", "C", "D"), 
                         revenue=c(3354823, 1284690, 8513581, 4699102))
x_cols <- scales::hue_pal()(length(levels(example_df$movie)))
names(x_cols) <- levels(example_df$movie)

ggplot(data=example_df) + geom_bar(aes(x=movie, y=revenue, fill=movie), stat="identity") +
  scale_y_continuous(labels = dollar_format(scale=10^-6, suffix="M")) +
  theme_bw() +
  theme(axis.text.x = element_text(angle=45, 
                                   colour=x_cols[substr(levels(example_df$movie),1,1)]),
        panel.grid = element_blank())

I would start with the statement that you may be over-complicating things not using geom_bar. It was designed precisely to handle the kind of data you want to show. Thus it would be profitable to stick with it. If you want to colour the labels of a bar plot with the same colours as bars themselves you could follow the trick shown here: Color axis labels by group, which I shamelessly applied to my example.

Ad. 1. This is the most tricky part to reproduce, and the reasons can be plenty. One sure way to circumvent that is to rotate names slightly, using angle parameter of the element_text function. This will work as long as you resort back to a bar plot.

Ad. 2. Use the great scales library. dollar_format is the function you look for (although the name is pretty confusing).

Ad. 3. panel.grid in the theme function.