Home > database >  How to plot a group data in a CIRCULAR plot with R?
How to plot a group data in a CIRCULAR plot with R?

Time:10-22

Does anyone knows how to expand the circular plot I just made below, and make it readable? I have been plotting this type of enter image description here

CodePudding user response:

The issue is the large range of your data, i.e. only the bars and labels for the four or five observations with high values are visible.

One option in such cases would be to display your data on a log scale, e.g. in my approach below I use log10.

Note: Besides that I made some small adjustments e.g. to add the grid lines.

# library
library(tidyverse)

data$topic <- factor(data$topic)
data$tag <- factor(data$tag)
data$value <- log10(data$value)

# 'empty bar' to add at the end of each group
empty_bar <- 3
to_add <- data.frame(matrix(NA, empty_bar * nlevels(data$topic), ncol(data)))
colnames(to_add) <- colnames(data)
to_add$topic <- rep(levels(data$topic), each = empty_bar)
data <- rbind(data, to_add)
data <- data %>% arrange(topic)
data$id <- seq(1, nrow(data))

# name and the y position of each label
label_data <- data
number_of_bar <- nrow(label_data)
angle <- 90 - 360 * (label_data$id - 0.5) / number_of_bar # I substract 0.5 because the letter must have the angle of the center of the bars. Not extreme right(1) or extreme left (0)
label_data$hjust <- ifelse(angle < -90, 1, 0)
label_data$angle <- ifelse(angle < -90, angle   180, angle)

# prepare a data frame for base lines
base_data <- data %>%
  group_by(topic) %>%
  summarize(start = min(id), end = max(id) - empty_bar) %>%
  rowwise() %>%
  mutate(title = mean(c(start, end)))

# prepare a data frame for grid (scales)
grid_data <- base_data
grid_data$end <- grid_data$end[c(nrow(grid_data), 1:nrow(grid_data) - 1)]   1
grid_data$start <- grid_data$start - 1
grid_data <- grid_data[-1, ]

# Make the plot
p <- ggplot(data, aes(x = as.factor(id), y = value, fill = topic))  
  geom_bar(aes(x = as.factor(id), y = value, fill = topic), stat = "identity", alpha = 0.5)  
  lapply(1:5, function(y) geom_segment(data = grid_data, aes(x = end, y = y, xend = start, yend = y), colour = "grey", alpha = 1, size = 0.3, inherit.aes = FALSE))  
  annotate("text", x = rep(max(data$id), 5), y = seq(5), label = scales::number(10^seq(5)), color = "grey", size = 3, angle = 0, fontface = "bold", hjust = 1)  
  geom_bar(aes(x = as.factor(id), y = value, fill = topic), stat = "identity", alpha = 4)  
  theme_minimal()  
  theme(
    legend.position = "none",
    axis.text = element_blank(),
    axis.title = element_blank(),
    panel.grid = element_blank(),
    plot.margin = unit(rep(-0.1, 5), "cm")
  )  
  coord_polar()  
  geom_text(
    data = label_data, aes(x = id, y = value   .1, label = tag, hjust = hjust),
    color = "black", fontface = "bold", alpha = 0.6, size = 2.5, angle = label_data$angle, inherit.aes = FALSE
  )  
  geom_text(
    data = label_data, aes(x = id, y = value - .1, label = scales::number(10^value), hjust = 1 - hjust),
    color = "black", fontface = "bold", alpha = 0.6, size = 2.5, angle = label_data$angle, inherit.aes = FALSE
  )  
  # Add base line information
  geom_segment(data = base_data, aes(x = start, y = -5, xend = end, yend = -5), colour = "black", alpha = 0.8, size = 0.6, inherit.aes = FALSE)

p

enter image description here

  • Related