Jacey
Jacey

Reputation: 11

Shiny - Can't get Barplot to display

Why does the barplot not display? If I run the same code outside of the larger program, the barplot is displayed. I get the radio buttons and the outline of the charts but no data on the inside. I have included the server and ui and data below. I am very new to shiny.

I have tried the brackets, commas, and parenthesis in multiple places. I have not found the solution.

UI.r
#UI Program
library(shiny)
library(shinydashboard)
library(ggplot2)
library(ggthemes)
library(DT)

# my data
my_data=read.table("hack.csv", header=T, sep=",")
# changing date to categorical data 
#my_data$Year=factor(my_data$Year)

## Preparing sidebar items
sidebar <- dashboardSidebar(
  width = 300,
  sidebarMenu(
    menuItem(h3("Dashboard"), tabName = "dashbd"),
    menuItem(h3("Data"), tabName = "datafile"),
    menuItem(h3("Visualization of Data"), tabName = "graphs", 
         menuSubItem(h4("- Barplot"), tabName = "crime")    ),

    br(),
    br(),
    hr()
  )
)
## Preparing for the body items
body <- dashboardBody(
  tabItems(
    tabItem(tabName = "dashbd",
        fluidRow(
          valueBoxOutput("vbox1", width = 6),
          valueBoxOutput("vbox2", width = 6)),
        h2("Introduction",  align = "center", style = "font-family: 'times'; color:blue"),
        h3("Cyber crime damage costs to hit $6 trillion annually by 2021. It all begins and ends with cyber crime. Without it, there's nothing to cyber-defend. The cybersecurity community and major media have largely concurred on the prediction that cyber crime damages will cost the world $6 trillion annually by 2021, up from $3 trillion in 2015. This represents the greatest transfer of economic wealth in history, risks the incentives for innovation and investment, and will be more profitable than the global trade of all major illegal drugs combined"),
        fluidPage(
          fluidRow(
            column(
              h2("About this app ...", align = "center", style = "font-family: 'times'; color:blue"),
              h3("This app helps you to explore and visualize the motivation behind cyber attacks
                 I have used the database available",  a("here.",href="https://www.hackmageddon.com/about/"), 
                 style = "font-family: 'times'"),
              width = 4,
              align = "left"

            ),
            column(
              h2("How to use!", style = "font-family: 'times'; color:blue"),
              h3("This app contains multiple sections;  the database and several visual graphs. ", 
                 style = "font-family: 'times'"),              
              width = 8,
              align = "left"
            ),
            br(),
            br()
            )
        ),
        p()
    ),  
    tabItem(tabName = "datafile",
        box(title = "Motivation of Cyber Attacks in Italy",
            width = 12, 
            DT::dataTableOutput('da.tab'))  
    ),

#the select for barplot
tabItem(tabName = "crime",
        titlePanel(title = h4("Cyber Attacks in Italy by Year", align="center")),
        sidebarPanel(

          radioButtons("YEAR", "Select the Census Year",
                       choices = c("2017", "2016", "2015","2014"),
                       selected = "2017")),


        sidebarPanel(
          plotOutput("MyBar"))
    )  

  )  )

# Show a plot of the generated distribution
## Putting them together into a dashboardPage

ui <- dashboardPage( 
  skin="blue",
  # add this -> navbarMenu()
  dashboardHeader(
    title="MOTIVATION BEHIND CYBER ATTACKS IN ITALY",
    titleWidth = 550,
    tags$li(class = "dropdown"
    )
  ),
  sidebar,
  body
)

SERVER
    # Reading data set
my_data=read.table("hack.csv", header=T, sep=",")
#number of row of data
my_data$Year=as.factor(my_data$Year)
server <- function(input, output) {
  ## Information for dashboard tab 
  # Reading data set
  my_data=read.table("hack.csv", header=T, sep=",")
  #number of row of data
  my_data$Year=as.factor(my_data$Year)

  server <- function(input, output) {



## Information for data tab
# data table output


output$da.tab <- DT::renderDataTable(datatable(my_data, extensions = 'Buttons',
                                               style = "bootstrap",
                                               filter = list(position = 'top', clear = T, plain = F),
                                               options = list(pageLength = 1500, dom = 'Bfrtip', 
                                                              buttons = 
                                                                list('copy', 'print', list(
                                                                  extend = 'collection',
                                                                  buttons = c('csv', 'excel', 'pdf'), 
                                                                  text = 'Download')
                                                                )
                                               )
    )    )


  }
  ## Information for data tab
  # data table output


  output$da.tab <- DT::renderDataTable(datatable(my_data, extensions = 'Buttons',
                                             style = "bootstrap",
                                             filter = list(position = 'top', clear = T, plain = F),
                                             options = list(pageLength = 1500, dom = 'Bfrtip', 
                                                            buttons = 
                                                              list('copy', 'print', list(
                                                                extend = 'collection',
                                                                buttons = c('csv', 'excel', 'pdf'), 
                                                                text = 'Download')
                                                              )
                                             )  )  )


  #This is used to create the BarPlot
  server <- function(input,output){

    reactive_data = reactive({
  #Reading from the datbase for year selected
  selected_year = as.numeric(input$YEAR)
  return(data[data$year==selected_year,])

    })
    #outputting the bar data
    output$bar <- renderPlot({
      color <- c("blue", "red", "yellow")

      our_data <- reactive_data()

      barplot(colSums(our_data[,c("CyberCrime","CyberWar","CyberHacks")]),
          ylab="Total",
          xlab="Census Year",
          names.arg = c("CyberCrime","CyberWar","CyberHacks"),
          col = color)
            })
      }}


DATA
#This is the data for the query
Year,CyberCrime,CyberWar,CyberHacks,CyberEspionage
2017,60,45,12,16
2016,65,40,16,14
2015,55,38,10,9
2014,50,26,9,6

Upvotes: 1

Views: 1400

Answers (2)

phalteman
phalteman

Reputation: 3542

@mlegge's answer is good (and should be the accepted answer) - the nested server functions were the main problem. But you can further simplify your server function. Because renderPlot is a reactive environment, you can subset the data inside your call to renderPlot like so:

output$MyBar <- renderPlot({
  our_data <- my_data[my_data$Year==input$YEAR,]
  color <- c("blue", "red", "yellow")

  barplot(colSums(our_data[,c("CyberCrime","CyberWar","CyberHacks")]),
          ylab="Total",
          xlab="Census Year",
          names.arg = c("CyberCrime","CyberWar","CyberHacks"),
          col = color)
})

This eliminates the unnecessary assignment to reactive_data

Upvotes: 0

mlegge
mlegge

Reputation: 6913

You did have a naming issue as Aurele pointed out in comments, but more worryingly you had nested server functions defined... I'm chalking it up to a bad copy-paste job, but here is a working version. I added a shiny::validate to make sure it didn't try to plot the barplot when there was no data.

library(shiny)
library(shinydashboard)
library(ggplot2)
library(ggthemes)
library(DT)

my_data <- read.table(text = "
Year,CyberCrime,CyberWar,CyberHacks,CyberEspionage
2017,60,45,12,16
2016,65,40,16,14
2015,55,38,10,9
2014,50,26,9,6", sep = ",", header = TRUE)


## Preparing sidebar items
sidebar <- dashboardSidebar(
  width = 300,
  sidebarMenu(
    menuItem(h3("Dashboard"), tabName = "dashbd"),
    menuItem(h3("Data"), tabName = "datafile"),
    menuItem(h3("Visualization of Data"), tabName = "graphs", 
             menuSubItem(h4("- Barplot"), tabName = "crime")    ),

    br(),
    br(),
    hr()
  )
)
## Preparing for the body items
body <- dashboardBody(
  tabItems(
    tabItem(tabName = "dashbd",
            fluidRow(
              valueBoxOutput("vbox1", width = 6),
              valueBoxOutput("vbox2", width = 6)),
            h2("Introduction",  align = "center", style = "font-family: 'times'; color:blue"),
            h3("Cyber crime damage costs to hit $6 trillion annually by 2021. It all begins and ends with cyber crime. Without it, there's nothing to cyber-defend. The cybersecurity community and major media have largely concurred on the prediction that cyber crime damages will cost the world $6 trillion annually by 2021, up from $3 trillion in 2015. This represents the greatest transfer of economic wealth in history, risks the incentives for innovation and investment, and will be more profitable than the global trade of all major illegal drugs combined"),
            fluidPage(
              fluidRow(
                column(
                  h2("About this app ...", align = "center", style = "font-family: 'times'; color:blue"),
                  h3("This app helps you to explore and visualize the motivation behind cyber attacks
                     I have used the database available",  a("here.",href="https://www.hackmageddon.com/about/"), 
                     style = "font-family: 'times'"),
                  width = 4,
                  align = "left"

                ),
                column(
                  h2("How to use!", style = "font-family: 'times'; color:blue"),
                  h3("This app contains multiple sections;  the database and several visual graphs. ", 
                     style = "font-family: 'times'"),              
                  width = 8,
                  align = "left"
                ),
                br(),
                br()
                )
            ),
            p()
    ),  
    tabItem(tabName = "datafile",
            box(title = "Motivation of Cyber Attacks in Italy",
                width = 12, 
                DT::dataTableOutput('da.tab'))  
    ),

    #the select for barplot
    tabItem(tabName = "crime",
            titlePanel(title = h4("Cyber Attacks in Italy by Year", align="center")),
            sidebarPanel(

              radioButtons("YEAR", "Select the Census Year",
                           choices = c("2017", "2016", "2015","2014"),
                           selected = "2017")),


            sidebarPanel(
              plotOutput("MyBar"))
    )  

  )  )

# Show a plot of the generated distribution
## Putting them together into a dashboardPage

ui <- dashboardPage( 
  skin="blue",
  # add this -> navbarMenu()
  dashboardHeader(
    title="MOTIVATION BEHIND CYBER ATTACKS IN ITALY",
    titleWidth = 550,
    tags$li(class = "dropdown"
    )
  ),
  sidebar,
  body
)


server <- function(input, output) {

  output$da.tab <- DT::renderDataTable(
    datatable(
      data = my_data, 
      extensions = 'Buttons',
      style = "bootstrap",
      filter = list(position = 'top', clear = T, plain = F),
      options = list(
        pageLength = 1500,
        dom = 'Bfrtip', 
        buttons = list(
          'copy', 
          'print',
          list(
            extend = 'collection',
            buttons = c('csv', 'excel', 'pdf'), 
            text = 'Download')
          ) #/ buttonList
        ) #/ options 
      ) #/ datatable
    ) #/ renderDataTable

  reactive_data = reactive({
    #Reading from the datbase for year selected
    my_data[my_data$Year == input$YEAR,]

  })

  #outputting the bar data
  output$MyBar <- renderPlot({
    color <- c("blue", "red", "yellow")

    our_data <- reactive_data()

    shiny::validate(
      need(nrow(our_data) > 0, "No data for that year!")
    )

    barplot(colSums(our_data[,c("CyberCrime","CyberWar","CyberHacks")]),
            ylab="Total",
            xlab="Census Year",
            names.arg = c("CyberCrime","CyberWar","CyberHacks"),
            col = color)
  })

}

shinyApp(ui, server)

enter image description here

Upvotes: 2

Related Questions