Does anyone knows how to expand the circular plot I just made below, and make it readable? I have been plotting this type of data, but return unexpected plot. Thank you in advance for the answer.
Code used:
# library
library(tidyverse)
# load your data (from files)
data <- read.csv("C:/Users/HP/Downloads/data.csv")
# '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) +
# Add a val=100/75/50/25 lines. I do it at the beginning to make sur barplots are OVER it.
geom_segment(data=grid_data, aes(x = end, y = 80, xend = start, yend = 80), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
geom_segment(data=grid_data, aes(x = end, y = 60, xend = start, yend = 60), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
geom_segment(data=grid_data, aes(x = end, y = 40, xend = start, yend = 40), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
geom_segment(data=grid_data, aes(x = end, y = 20, xend = start, yend = 20), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
# Add text showing the value of each 100/75/50/25 lines
annotate("text", x = rep(max(data$id),4), y = c(20, 40, 60, 80), label = c("20", "40", "60", "80") , 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) +
ylim(-300,70000) +
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+10, label=tag, hjust=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 ) +
geom_text(data=base_data, aes(x = title, y = -18, label=topic), hjust=c(1,1,1,0,0), colour = "black", alpha=0.8, size=4, fontface="bold", inherit.aes = FALSE)
p
Running the code returned the plot below which is impossible to read:
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