Load packages

packages <- c("tidyverse","plotly","shiny")
for (p in packages){
  if(!require (p, character.only = T)){
    install.packages(p)
  }
  library(p, character.only = T)
}

Load data and check the levels

Here the data is about the consumption and production of main meat type in major areas, from 2001 to 2018.

data <- read.csv("E:/VA demo/data/01_consumption&production.csv")
glimpse(data)
## Observations: 2,520
## Variables: 8
## $ X                   <int> 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,...
## $ Area                <fct> Republic of Korea, Republic of Korea, Republic ...
## $ Location            <fct> KOR, KOR, KOR, KOR, KOR, KOR, KOR, KOR, KOR, KO...
## $ Item                <fct> SHEEP, SHEEP, SHEEP, SHEEP, SHEEP, SHEEP, SHEEP...
## $ Year                <int> 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,...
## $ consumption.tonnes. <dbl> 4889, 5699, 5512, 5978, 6078, 5838, 5819, 5730,...
## $ production.tonnes.  <dbl> 3000, 3000, 4000, 4000, 5000, 6000, 8000, 13000...
## $ Flag                <fct> Demanding, Demanding, Demanding, Demanding, Dem...
levels(data$Area)
##  [1] "Argentina"                                           
##  [2] "Australia"                                           
##  [3] "Brazil"                                              
##  [4] "Canada"                                              
##  [5] "Chile"                                               
##  [6] "China, mainland"                                     
##  [7] "Colombia"                                            
##  [8] "Egypt"                                               
##  [9] "Ethiopia"                                            
## [10] "India"                                               
## [11] "Indonesia"                                           
## [12] "Iran (Islamic Republic of)"                          
## [13] "Israel"                                              
## [14] "Japan"                                               
## [15] "Kazakhstan"                                          
## [16] "Malaysia"                                            
## [17] "Mexico"                                              
## [18] "New Zealand"                                         
## [19] "Nigeria"                                             
## [20] "Norway"                                              
## [21] "Pakistan"                                            
## [22] "Paraguay"                                            
## [23] "Peru"                                                
## [24] "Philippines"                                         
## [25] "Republic of Korea"                                   
## [26] "Russian Federation"                                  
## [27] "Saudi Arabia"                                        
## [28] "South Africa"                                        
## [29] "Switzerland"                                         
## [30] "Thailand"                                            
## [31] "Turkey"                                              
## [32] "Ukraine"                                             
## [33] "United Kingdom of Great Britain and Northern Ireland"
## [34] "United States of America"                            
## [35] "Viet Nam"
levels(factor(data$Year))
##  [1] "2001" "2002" "2003" "2004" "2005" "2006" "2007" "2008" "2009" "2010"
## [11] "2011" "2012" "2013" "2014" "2015" "2016" "2017" "2018"
levels(data$Item)
## [1] "BEEF"    "PIG"     "POULTRY" "SHEEP"

Load attribute function

vline() and hline() will be used to add reference line of our later plot.

# viline is a black vertical line
vline <- function(x = 0, color = "black") {
  list(
    type = "line", 
    y0 = 0, 
    y1 = 1, 
    yref = "paper",
    x0 = x, 
    x1 = x, 
    line = list(color = color)
  )
}

# hline is a black horizontal line
hline <- function(y = 0, color = "black") {
  list(
    type = "line", 
    x0 = 0, 
    x1 = 1, 
    xref = "paper",
    y0 = y, 
    y1 = y, 
    line = list(color = color)
  )
}

Load plot function

# Wrap the plot in a function for reuse
drawplot <- function(item){
  # prepare data for visualization:
  # filter the data by meat item
  # calculate mean and max values for reference
  df <-   data %>%
  filter(Item==item)
  xbar <- mean(df$production.tonnes.)
  ybar <- mean(df$consumption.tonnes.)
  xmax <- max(df$production.tonnes.)
  ymax <- max(df$consumption.tonnes.)
  Max <- mean(xmax,ymax)
  Bar <- mean(xbar,ybar)
  
# Draw interactive scatter plot on updated data via plotly
  plot_ly(df,
          type = "scatter",
          
          # set production at x axis and set consumption at y-axis
          x=~production.tonnes., 
          y=~consumption.tonnes.,
          
          # add animation by year
          frame = ~Year,
          
          # add color and hoverinfo by the area name
          name = ~Area,
          
          # mannually set the size of plot
          width = 500,
          height = 500) %>%
    
  # must hide the name legend since it occupies too much space.
  hide_legend() %>%

  layout(
    
    # add two vertical reference lines and two horizontal reference lines
    shapes = list(vline(Bar),hline(Bar),vline(Max-Bar),hline(Max-Bar)),

    # update the title with meat item filters
    title = paste(item, "prod. v/s cons. (tonnes)"),
    
    # though coordinate_equal() does not work, we can manually make two axis equal
    # update axis labels with item filer and,
    # we do not care about zeros so just hide zerolines
    # NOTE: gridline can also function as reference line as we keep it here
    xaxis = list(
      range = c(-Bar,Max+Bar),
      title = paste(item, "Production(tonnes)"),
      zeroline = FALSE
    ),
    yaxis = list(
      range = c(-Bar,Max+Bar),
      title = paste(item, "Consumption(tonnes)"),
      zeroline = FALSE
    ),
    
    annotations = list(
      # annotate the plot, indicating the areas with low meat production and consumption have only regional effect while others affect the world.
      list(
        x = Bar,
        y = Bar,
        text = "Regional|Global",
        xref = "x",
        yref = "y",
        showarrow = TRUE,
        arrowhead = 7,
        ax = -6,
        ay = -60
    ),
    
    # annotate the plot, indicating the areas with ultra high meat production and consumption will have global control of meat market
    list(
        x = Max-Bar,
        y = Max-Bar,
        text = "Global dominator",
        xref = "x",
        yref = "y",
        showarrow = TRUE,
        arrowhead = 7,
        ax = -60,
        ay = 20
    )
  )
  )
}

# visualize beef production and consumption in each area and over years 
drawplot("BEEF")
## No scatter mode specifed:
##   Setting the mode to markers
##   Read more about this attribute -> https://plot.ly/r/reference/#scatter-mode

Glimpse of Shiny

Though plotly provide tools for custom control — updatemenus, it is not as clear as shiny. So here we still rely on shiny to custom the plot

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
    
      # add a selector of meat items
      selectInput("item",
                  "Meat Item: ",
                  choices = levels(data$Item),
                  selected = "BEEF")
    ),
    mainPanel(
      plotlyOutput("Plot")
    )
  )
)
server <- function(input, output) {
  output$Plot <- renderPlotly({
    drawplot(input$item)
  })
}
shinyApp(ui, server)
Shiny applications not supported in static R Markdown documents