packages <- c("tidyverse","plotly","shiny")
for (p in packages){
if(!require (p, character.only = T)){
install.packages(p)
}
library(p, character.only = T)
}
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"
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)
)
}
# 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
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)