Reputation: 2863
I have a pie chart below, and I would like to create the wheel much more readable. many thanks in advance.
library(ggplot2)
library(dplyr)
# Create Data
data <- data.frame(
group=c("IMAGINE HERE I HAVE A LONG SURVEY QUESTIONS",
"AND THE TEXT IS IN DIFFERENT LENGTH",
"WANNA PLOT THESE IN ORDER",
"WITH 45 DEGREE ANGLE",
"PIE CAN BE PROPORTIONAL WITH THE TEXT LENGTH" ),
value=c(13,7,9,21,2)
)
# Compute the position of labels
data <- data %>%
arrange(desc(group)) %>%
mutate(prop = value / sum(data$value) *100) %>%
mutate(ypos = cumsum(prop)- 0.5*prop )
# Basic piechart
ggplot(data, aes(x="", y=prop, fill=group)) +
geom_bar(stat="identity", width=1, color="white") +
coord_polar("y", start=0) +
theme_void() +
theme(legend.position="none") +
geom_text(aes(y = ypos, label = group), color = "white", size=6) +
scale_fill_brewer(palette="Set1")
Upvotes: 0
Views: 310
Reputation: 41603
It is not the best option, but you could use geom_label_repel
from ggrepel
like this:
library(ggplot2)
library(dplyr)
library(ggrepel)
data <- data %>%
arrange(desc(group)) %>%
mutate(prop = value / sum(data$value) *100) %>%
mutate(ypos = cumsum(prop)- 0.5*prop )
ggplot(data, aes(x="", y=prop, fill=group)) +
geom_bar(stat="identity", width=1, color="white") +
coord_polar("y", start=0) +
theme_void() +
theme(legend.position="none") +
geom_label_repel(data = data,
aes(y = ypos, label = group),
size = 4.5, nudge_x = 3, show.legend = FALSE) +
scale_fill_brewer(palette="Set1")
Output:
Upvotes: 1
Reputation: 76673
Maybe to wrap the group
text and have it plotted in many lines of text is a way to solve the problem.
First strwrap
breaks each value in group
, then paste
inserts newline characters at the break points.
And the graphics device dimensions are made larger, though it doesn't show with reprex
.
suppressPackageStartupMessages({
library(ggplot2)
library(dplyr)
})
# Create Data
data <- data.frame(
group=c("IMAGINE HERE I HAVE A LONG SURVEY QUESTIONS",
"AND THE TEXT IS IN DIFFERENT LENGTH",
"WANNA PLOT THESE IN ORDER",
"WITH 45 DEGREE ANGLE",
"PIE CAN BE PROPORTIONAL WITH THE TEXT LENGTH" ),
value=c(13,7,9,21,2)
)
# Compute the position of labels
data <- data %>%
arrange(desc(group)) %>%
mutate(prop = value / sum(data$value) *100) %>%
mutate(ypos = cumsum(prop) - 0.5*prop )
data$group2 <- sapply(data$group, \(x) {
s <- strwrap(x, width = 15)
paste(s, collapse = "\n")
})
old_par <- par()[c("fin", "mar")]
par(fin = old_par$fin + 5, mar = rep(0, 4))
# Basic piechart
ggplot(data, aes(x="", y=prop, fill=group)) +
geom_bar(stat="identity", width=1, color="white") +
coord_polar("y", start=0) +
theme_void() +
theme(legend.position="none") +
geom_text(aes(y = ypos, label = group2), color = "white", size=3) +
scale_fill_brewer(palette="Set1")
par(old_par)
Created on 2022-05-29 by the reprex package (v2.0.1)
Upvotes: 3
Reputation: 174586
You have a better chance of fitting in the labels if you wrap them using str_wrap
and curve them using geomtextpath
:
# Compute the position of labels
data <- data %>%
arrange(desc(group)) %>%
mutate(prop = value / sum(data$value) *100) %>%
mutate(ypos = cumsum(prop)- 0.5*prop,
group = stringr::str_wrap(group, 20))
library(geomtextpath)
# Basic piechart
ggplot(data, aes(x=1, y=prop, fill=group)) +
geom_bar(stat="identity", width=1, color="white") +
coord_polar("y", start=0) +
theme_void() +
theme(legend.position="none") +
geom_textpath(aes(x = 1.3, y = ypos, label = group,
vjust = group), color = "black", size = 6,
angle = 90) +
scale_fill_brewer(palette="Set1") +
scale_x_continuous(limits = c(0.5, 2)) +
scale_vjust_manual(values = c(2, 1.8, 2.2, 2, 4))
Upvotes: 4