3

I want to plot a radar plot like followed and replace the Var notations with the unique values of the rows and group it by the columns (right side is what I want to accomplish, ignore blue area):

enter image description here enter image description here

I have followed dataframe structure:

# install.packages("fmsb")
library(fmsb)
ser <- rep(c(4.5, 3.0, 4.0, 1.0, 1.0, 3.5, 4.5, 3.0, 3.0, 4.0, 
               3.0, 4.5, 4.5, 4.0, 3.0, 1.5, 1.5, 2.0, 2.0,
               3.5, 4.5, 3.5, 3.0, 3.0, 4.5, 4.5, 2.5, 4.5),100)

avg <- rep(c(4.5, 3.5, 4.0, 1.0, 4.0, 3.5, 4.5, 4.0, 1.0, 4.0, 
               3.0, 4.5, 4.0, 3.0, 1.5, 1.5, 2.0, 2.0,
               3.5, 4.5, 3.5, 3.5, 4.0, 3.0, 4.0, 4.0, 2.5, 4.5),100)

df <- data.frame(ser, avg)

Example code of the left plot here.

Note for Bounty: Similiar solutions with ggplot are also accepted.

JAdel
  • 1,309
  • 1
  • 7
  • 24

3 Answers3

4

You can also use the ggradar function from the ggradar package.

library(tidyverse)
library(ggradar)

df = tibble(
  ser = rep(c(4.5, 3.0, 4.0, 1.0, 1.0, 3.5, 4.5, 3.0, 3.0, 4.0, 
             3.0, 4.5, 4.5, 4.0, 3.0, 1.5, 1.5, 2.0, 2.0,
             3.5, 4.5, 3.5, 3.0, 3.0, 4.5, 4.5, 2.5, 4.5),100),
  avg = rep(c(4.5, 3.5, 4.0, 1.0, 4.0, 3.5, 4.5, 4.0, 1.0, 4.0, 
             3.0, 4.5, 4.0, 3.0, 1.5, 1.5, 2.0, 2.0,
             3.5, 4.5, 3.5, 3.5, 4.0, 3.0, 4.0, 4.0, 2.5, 4.5),100))

df %>% pivot_longer(everything()) %>% 
  group_by(name, value) %>% 
  summarise(n = n()/1000) %>% 
  pivot_wider(names_from = value, values_from = n) %>% 
  ggradar(grid.label.size = 4, axis.label.size = 4) 

enter image description here

Marek Fiołka
  • 4,825
  • 1
  • 5
  • 20
3

In order to use the unique values instead of the "Var" names with fmsb::radarchart, we need to reformat the data into a dataframe which has these values as column names, and the respective values per group as rows, which can be done e.g. using the tidyverse:

library(dplyr)
library(tidyr)

# prepare data for radarplot format
df1 <- df %>%
  tidyr::pivot_longer(c(ser, avg)) %>%
  group_by(name, value) %>% 
  #whatevery summary statistic required
  dplyr::summarise(target_stat = n()/nrow(df)) %>%
  tidyr::pivot_wider(id_cols = "name", 
                     names_from = "value", 
                     values_from = "target_stat") %>%
  # ensure numeric values of column names are in correct order
  dplyr::select(order(colnames(.))) %>%
  dplyr::ungroup()

# keep group labels in correct order for later
gr_names <- df1$name

#remove names from plot data
df1 <- df1 %>%
  dplyr::select(-name)

In addition, we need to add two rows for Max and Min values of each axis on top if we want to control the axis ranges (here: same ranges for all variables). As pointed out in another answer, this step is not required with radarchart(..., maxmin = FALSE) if independent auto-scaling of each axis is acceptable.

# specify max & min rows
df_min_max <- data.frame(
  rbind(
    rep(max(df1), ncol(df1)),
    rep(0, ncol(df1)))
)

#combine ranges and data
colnames(df_min_max) <-  colnames(df1)
df_plot <- bind_rows(df_min_max, df1)  

df_plot

#     1  1.5    2  2.5    3  3.5    4  4.5
#1 3600 3600 3600 3600 3600 3600 3600 3600
#2    0    0    0    0    0    0    0    0
#3  200  300  400  250 2100 1050 1200 3600
#4  200  300  400  250  900 1750 3200 2250

This can then be used similar to the example code linked in the question.

## specify colors
col_points <- c(rgb(1, 0, 0), rgb(0, 0, 1))
col_areas <- c(rgb(1, 0, 0, 0.2), rgb(0, 0, 1, 0.2))


df_plot %>% 
  radarchart(
    pcol = col_points,
    pfcol = col_areas)

legend("topright",
       legend = gr_names,
       bty = "n", pch = 20, col = col_areas,
       pt.cex = 2)

enter image description here

pholzm
  • 1,719
  • 4
  • 11
  • @I_O added the following (but could not comment yet): (1) you can skip the Max and Min row when calling `radarchart` with `maxmin=FALSE` (2) `radarchart` plots counter-clockwise which can be confusing for variables with rankable names (like in your case). If desired, reverse column order of any data.frame like this: `df_reverse <- rev(df)` – pholzm Feb 26 '22 at 11:55
2

notes to above solutions (can't comment yet):

  • you can skip the Max and Min row when calling radarchart with maxmin=FALSE
  • radarchart plots counter-clockwise which can be confusing for variables with rankable names (like in your case). If desired, reverse column order of any data.frame like this: df_reverse <- rev(df).