Search code examples
rshinydata-visualizationaxis-labelsradar-chart

How to move radar chart / spider chart labels in R fmsb for R Shiny so labels don't overlap with plot?


I have a shiny app that creates a spider plot using the fmsb package based on users input on a short quiz. However, 2 of the labels, overlap with the plot, and I cannot find a way to move them further out.

enter image description here

I've tried playing with the paxislabels argument, but I cannot figure it out and the help documentation or this great tutorial isn't clear on that portion. I want the horizontal labels to be like the vertical ones--outside of the plot.

Here's a reproducible example:


library(shiny)
library(fmsb)
library(ggplot2)

ui <- fluidPage(


    sidebarLayout(
        sidebarPanel(                     selectInput("q1", label = "question 1", choices = c("", "Yes" = 1, "Somewhat" = .5, "No" = 0)),
                                          selectInput("q2", label = "question 2", choices = c("", "Yes" = 1, "Somewhat" = .5, "No" = 0)),
                                          selectInput("q3", label = "question 3", choices = c("", "Yes" = 1, "Somewhat" = .5, "No" = 0)),
                                          selectInput("q4", label = "question 4", choices = c("", "Yes" = 1, "Somewhat" = .5, "No" = 0)),
                                          selectInput("q5", label = "question 5", choices = c("", "Yes" = 1, "Somewhat" = .5, "No" = 0)),
                                          selectInput("q6", label = "question 6", choices = c("", "Yes" = 1, "Somewhat" = .5, "No" = 0)),
                                          selectInput("q7", label = "question 7", choices = c("", "Yes" = 1, "Somewhat" = .5, "No" = 0)),
                                          actionButton("submit", "Submit")),

        mainPanel(
            mainPanel(plotOutput("spider_chart"))
        )
    )
)

server <- function(input, output) {
    
    data_scores <- reactive({
        
        #Make tibble of raw data
        raw_data <- tibble(`Variable 1` = sum(c(as.numeric(input$q1), as.numeric(input$q2), na.rm = T)),
                              `Variable 2` = sum(c(as.numeric(input$q2), as.numeric(input$q3)), na.rm = T),
                              `Variable 3` = sum(c(as.numeric(input$q4), as.numeric(input$q5)), na.rm = T),
                              `Variable 4` = sum(c(as.numeric(input$q5), as.numeric(input$q6), as.numeric(input$q7)), na.rm = T))
    
        #fbsm needs the first 2 rows to be the max and min values
        min_max <- tibble(`Variable 1` = c(2, 0),
                          `Variable 2` = c(2, 0),
                          `Variable 3` = c(2, 0),
                          `Variable 4` = c(3, 0))
        
        min_max %>%
            full_join(raw_data)
        
    })
    
#This is the section that needs to be updated
    output$spider_chart <- renderPlot({
        req(input$submit)
        
        colors_border=rgb(.5, 0, .5, .9)
        colors_in=rgb(.5, 0, .5, .5)
        
        # plot with default options:
        radarchart(data_scores(), 
                   #custom polygon
                   pcol=  colors_border, pfcol=colors_in , plwd=4 , plty=1,
                   #custom the grid
                   cglcol="grey", cglty=1, axislabcol="grey",cglwd=0.8, paxislabels = c(10, 10, 10, 10),
                   #custom labels
                   vlcex= 1.2
        )  })

}

# Run the application 
shinyApp(ui = ui, server = server)

Solution

  • I wrote directly to the creator of fmsb, Minato Nakazawa, and he provided an extremely easy to implement answer. In short, all the labels act like general text strings, so he suggested renaming the variables using the vlabel argument within my radarchart() call and adding spaces to the two horizontal axis titles, and it worked! Below is what it looks like with adding 10 spaces:

    enter image description here

    Here's the full code with the addition:

    
    library(shiny)
    library(fmsb)
    library(ggplot2)
    
    ui <- fluidPage(
    
    
        sidebarLayout(
            sidebarPanel(                     selectInput("q1", label = "question 1", choices = c("", "Yes" = 1, "Somewhat" = .5, "No" = 0)),
                                              selectInput("q2", label = "question 2", choices = c("", "Yes" = 1, "Somewhat" = .5, "No" = 0)),
                                              selectInput("q3", label = "question 3", choices = c("", "Yes" = 1, "Somewhat" = .5, "No" = 0)),
                                              selectInput("q4", label = "question 4", choices = c("", "Yes" = 1, "Somewhat" = .5, "No" = 0)),
                                              selectInput("q5", label = "question 5", choices = c("", "Yes" = 1, "Somewhat" = .5, "No" = 0)),
                                              selectInput("q6", label = "question 6", choices = c("", "Yes" = 1, "Somewhat" = .5, "No" = 0)),
                                              selectInput("q7", label = "question 7", choices = c("", "Yes" = 1, "Somewhat" = .5, "No" = 0)),
                                              actionButton("submit", "Submit")),
    
            mainPanel(
                mainPanel(plotOutput("spider_chart"))
            )
        )
    )
    
    server <- function(input, output) {
        
        data_scores <- reactive({
            
            #Make tibble of raw data
            raw_data <- tibble(`Variable 1` = sum(c(as.numeric(input$q1), as.numeric(input$q2), na.rm = T)),
                                  `Variable 2` = sum(c(as.numeric(input$q2), as.numeric(input$q3)), na.rm = T),
                                  `Variable 3` = sum(c(as.numeric(input$q4), as.numeric(input$q5)), na.rm = T),
                                  `Variable 4` = sum(c(as.numeric(input$q5), as.numeric(input$q6), as.numeric(input$q7)), na.rm = T))
        
            #fbsm needs the first 2 rows to be the max and min values
            min_max <- tibble(`Variable 1` = c(2, 0),
                              `Variable 2` = c(2, 0),
                              `Variable 3` = c(2, 0),
                              `Variable 4` = c(3, 0))
            
            min_max %>%
                full_join(raw_data)
            
        })
        
    #This is the section that needs to be updated
        output$spider_chart <- renderPlot({
            req(input$submit)
            
            colors_border=rgb(.5, 0, .5, .9)
            colors_in=rgb(.5, 0, .5, .5)
            
            # plot with default options:
            radarchart(data_scores(), 
                       #custom polygon
                       pcol=  colors_border, pfcol=colors_in , plwd=4 , plty=1, vlabels = c("Variable 1", "Variable 2          ", "Variable 3", "          Variable 4"),
                       #custom the grid
                       cglcol="grey", cglty=1, axislabcol="grey",cglwd=0.8, paxislabels = c(10, 10, 10, 10),
                       #custom labels
                       vlcex= 1.2
            )  })
    
    }
    
    # Run the application 
    shinyApp(ui = ui, server = server)
    
    

    A huge thank you to Minato Nakazawa for creating this package and for his prompt reply to my inquiry.