Adding lines to the donut chart in ggplot2
I've been trying to create a chart that displays values outside its perimeter for a long time. I would like to connect these values to the corresponding segments on the chart using dashed lines that should start at the centers of the segments. my plot I was able to create a chart that met the requirements except for the (seemingly) trivial lines using this code:
library(ggplot2)
library(dplyr)
COUNTRY <- c("Sweden", "France", "USA", "Britain", "Argentina", "Brazil")
Revenue <- c(190, 146, 131, 129, 121, 937)
Percent <- c(0.11487304, 0.08827086, 0.07920193, 0.07799274, 0.07315599, 0.56650544)
color <- c('A', 'B', 'C', 'D', 'E', 'F')
TOP_5 <- data.frame(COUNTRY, Revenue, Percent, color)
colors <- c('A'='#D9553B', 'B'='#E17A65', 'C'='#EBA799', 'D'='#F2C8C0', 'E'='#F9E3DF', 'F'='#A7A8A9')
PLOT <- ggplot(data = TOP_5, aes(x = 2, y = Percent, fill = color)) +
geom_col(color = "white") +
coord_polar("y", start = 1) +
geom_text(aes(x = 3, label = paste0(" ", round(Percent * 100), "%")),
position = position_stack(vjust = 0.5),
hjust = 0,
angle = 0,
color = "black") +
geom_text(aes(x = 3, label = COUNTRY),
position = position_stack(vjust = 0.5),
hjust = 1,
angle = 0,
color = "#B43C23") +
geom_point(position = position_stack(vjust = 0.5),
color = "#B43C23",
size = 3) +
theme(panel.background = element_blank(),
axis.line = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
axis.title = element_blank(),
plot.title = element_text(hjust = 0.5, size = 18)) +
scale_fill_manual(values = colors) +
theme(legend.position = "none") +
xlim(0.5, 3.2)
The expected result would be something like this: desired plot I tried to achieve this using geom_segment but without success. I would appreciate your help in convicting a possible solution. Ideally, I would like to limit myself to just these two libraries, but of course I am open to additional solutions
One option to achieve your desired result would be to use a geom_segment
to connect the labels and the points. To this end I computed the y
positions manually. Additionally I switched to geom_label
as it allows for "background" box around the labels:
library(ggplot2)
library(dplyr)
TOP_5 <- TOP_5 %>%
arrange(desc(color)) %>%
mutate(
Percent_cum = cumsum(Percent),
y = .5 * (Percent_cum + lag(Percent_cum, default = 0))
)
ggplot(data = TOP_5, aes(x = 2, y = Percent, fill = color)) +
geom_col(color = "white") +
coord_polar("y", start = 1, clip = "off") +
geom_segment(aes(x = 2.1, xend = 3, y = y, yend = y, group = color)) +
geom_label(aes(x = 3, label = paste0(" ", round(Percent * 100), "%")),
position = position_stack(vjust = 0.5),
fill = "white",
label.size = 0,
hjust = 0,
angle = 0,
color = "black"
) +
geom_label(aes(x = 3, label = COUNTRY),
position = position_stack(vjust = 0.5),
fill = "white",
label.size = 0,
hjust = 1,
angle = 0,
color = "#B43C23"
) +
geom_point(
position = position_stack(vjust = 0.5),
color = "#B43C23",
size = 3
) +
theme(
panel.background = element_blank(),
axis.line = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
axis.title = element_blank(),
plot.title = element_text(hjust = 0.5, size = 18)
) +
scale_fill_manual(values = colors) +
theme(legend.position = "none") +
xlim(0.5, 3.2)