Search code examples
rshinyradar-chartspider-chart

How do I make an interactive radar chart in r shiny?


I'm pretty new to r and shiny and I am currently working on my first personal project. My project is about Pokemon and I am currently having trouble creating an interactive radar chart. I have tried looking at other questions about on this website about r and radar charts but couldn't really find the right answer since the dataset was usually in a different format, and the answers didn't provide a way to do it interactively.

What I'm trying to achieve: Create an interactive radar chart where the user can select a Pokemon and the radar chart will display that Pokemon's base stats (hp, attack, defense, etc.)

dataset:

       name hp defense attack sp_attack sp_defense speed
1  Bulbasaur 45      49     49        65         65    45
2    Ivysaur 60      63     62        80         80    60
3   Venusaur 80     123    100       122        120    80
4 Charmander 39      43     52        60         50    65
5 Charmeleon 58      58     64        80         65    80
6  Charizard 78      78    104       159        115   100
...

ui.R:

library(shiny)
library(plotly)


ui <- navbarPage(title = "Pokemon Research",
                 tabPanel(title = "Types and Stats",
                          sidebarPanel(
                            selectInput(inputId = "diff_stat", 
                                        label = "Different Types and their Base Statistics",
                                        choices = c("hp", "attack", "defense", "special_attack", 
                                                    "special_defense", "speed", "total"))
                          ),
                          mainPanel(plotlyOutput("type"))),
                 tabPanel(title = "Pokemon Statistics",
                          sidebarPanel(
                            selectInput(inputId = "indv",
                                        label = "Pokemon",
                                        choices = data$name
                          ),
                          #IDK WHAT TO PUT HERE FOR THE MAINPANEL
                          )))
                          

server.R:

library("shiny")
library("ggplot2")

data <- read.csv("../data/pokemon.csv", stringsAsFactors = FALSE)

type_data <- data %>% 
  select(name, type1, hp, defense, attack, sp_attack, sp_defense, speed) %>% 
  group_by(type1) %>% 
  summarise(hp = mean(hp),
            attack = mean(attack),
            defense = mean(defense),
            special_attack = mean(sp_attack),
            special_defense = mean(sp_defense),
            speed = mean(speed),
            total = mean(attack + defense + hp + sp_attack + sp_defense + speed))

indv_data <- data %>% 
  select(name, hp, defense, attack, sp_attack, sp_defense, speed)

server <- function(input, output) {
  output$type <- renderPlotly({
    ggplot(data = type_data, mapping = aes_string(x = "type1", y = input$diff_stat)) +
      geom_line(group = 1) +
      geom_point() +
      labs(x = "Types",
           y = "Base Stat (avg)")
  })
  output$radar <- renderPlot({
    #WHAT DO I PUT HERE TO MAKE THE RADAR CHART
  })
}

Any help is greatly appreciated!


Solution

  • This can help. I only included the code for the radar chart.

    library(tidyverse)
    library(shiny)
    library(plotly)
    
    pokemons <- 
    read_table('
      name      hp  defense attack sp_attack sp_defense speed
      Bulbasaur 45      49     49        65         65    45
        Ivysaur 60      63     62        80         80    60
       Venusaur 80     123    100       122        120    80
     Charmander 39      43     52        60         50    65
     Charmeleon 58      58     64        80         65    80
      Charizard 78      78    104       159        115   100')
    
    
    
    ui <- navbarPage(title = "Pokemon Research",
    
                     tabPanel(title = "Pokemon Statistics",
                              sidebarPanel(
                                  selectInput(inputId = "indv",
                                              label = "Pokemon",
                                              choices = pokemons$name, 
                                              selected = 'Bulbasaur')
                                  ),
                              mainPanel(
                                  plotlyOutput('radar') #the radar plot
                              )
                              ))
    
    server <- function(input, output, session) {
    
        output$radar <- renderPlotly({
            pkmn <- filter(pokemons, name == input$indv)
            
            r <- map_dbl(pkmn[, 2:6], ~.x)
            nms <- names(r)
            
            #code to plot the radar
            fig <- plot_ly(
                type = 'scatterpolar',
                r = r,
                theta = nms,
                fill = 'toself',
                mode = 'markers'
            ) 
            fig <- fig %>%
                layout(
                    polar = list(
                        radialaxis = list(
                            visible = T,
                            range = c(0,max(r))
                        )
                    ),
                    showlegend = F
                )
        })
    }
    
    shinyApp(ui, server)