Labeling pie charts using ggplot2 - r

I have this code:
as_tibble(earlyCiliated[[]]) %>%
ggplot(aes(x="", y=Phase, fill=Phase)) + geom_col() +
coord_polar("y", start=0) +
geom_text(aes(label = paste0(Phase, "%")))
and my output looks like this:
What am I doing wrong that's causing the labels to all be on top of each other?

I can't completely recreate your plot because I do not have your data. That being said, you can try this:
install.packages("ggrepel")
library(ggrepel)
as_tibble(earlyCiliated[[]]) %>%
ggplot(aes(x="", y=Phase, fill=Phase)) + geom_col() +
coord_polar("y", start=0) +
geom_label_repel(data = earlyCiliated[[]],
aes(y = Phase, label = paste0(Phase, "%")),
size = 4.5, nudge_x = 1, show.legend = FALSE)
This is what it will look like (using other data because none was provided)
library(ggplot2)
library(ggrepel)
library(tidyverse)
df <- data.frame(value = c(15, 25, 32, 28),
group = paste0("G", 1:4))
# Get the positions
df2 <- df %>%
mutate(csum = rev(cumsum(rev(value))),
pos = value/2 + lead(csum, 1),
pos = if_else(is.na(pos), value/2, pos))
ggplot(df, aes(x = "" , y = value, fill = fct_inorder(group))) +
geom_col(width = 1, color = 1) +
coord_polar(theta = "y") +
scale_fill_brewer(palette = "Pastel1") +
geom_label_repel(data = df2,
aes(y = pos, label = paste0(value, "%")),
size = 4.5, nudge_x = 1, show.legend = FALSE) +
guides(fill = guide_legend(title = "Group")) +
theme_void()

Related

plot data and their means in the same graph using ggplot

using the data set airquality I have written the following code:
library("tidyverse")
data(airquality)
airquality <- na.omit(airquality)
airquality$date <- as.Date(paste("1973", airquality$Month, airquality$Day,
sep="-"))
p1 <- ggplot(airquality, aes(x= date, y = Ozone, col=factor(Month))) +
geom_point() +
geom_line()
p1
Now I would like to plot in the same graph the mean of ozone for each months. How can I do this?
You could add the mean as a dashed line. The easiest way to do this might be to simply pass the data you want to a geom_line layer:
ggplot(airquality, aes(x = date, y = Ozone, col = factor(Month))) +
geom_point() +
geom_line(alpha = 0.5) +
geom_line(data = airquality %>%
group_by(Month) %>%
summarise(Ozone = mean(Ozone),
date = c(first(date), last(date)),
Month = mean(Month)),
linetype = 2, size = 1) +
scale_color_brewer(palette = "Set1") +
theme_minimal(base_size = 16)
If you just want points showing the mean, you could simplify things with stat_mean from ggpubr
ggplot(airquality, aes(x = date, y = Ozone, col = factor(Month))) +
geom_point() +
geom_line(alpha = 0.5) +
ggpubr::stat_mean(size = 5, shape = 21,
aes(fill = factor(Month)), color = "black") +
scale_color_brewer(palette = "Set1") +
scale_fill_brewer(palette = "Set1") +
theme_minimal(base_size = 16)
To join these dots up, you could do:
ggplot(airquality, aes(x = date, y = Ozone, col = factor(Month))) +
geom_point() +
geom_line(alpha = 0.5) +
geom_line(data = airquality %>%
group_by(Month) %>%
summarise(Ozone = mean(Ozone), date = mean(date)),
color = "black", linetype = 2) +
ggpubr::stat_mean(size = 5, shape = 21,
aes(fill = factor(Month)), color = "black") +
scale_color_brewer(palette = "Set1") +
scale_fill_brewer(palette = "Set1") +
theme_minimal(base_size = 16)

Drawing arrows in pie chart with ggplot2

For the data frame below, how can I display labels outside the circle with arrows pointing at them?
asd <- data.frame(a=c("fs","dfg","gf"), b=c(3,5,6))
ggplot(asd, aes(x="", y= b, fill = factor(a))) +
geom_bar(stat = "identity", width =1) +
coord_polar(theta = "y") + theme_void() +
geom_text(aes(label=paste(a, sep = " ", b, "%"), x= 1.3, angle = 0))
Try with this:
library(ggplot2)
library(dplyr)
asd <- data.frame(a = c("fs","dfg","gf"),
b = c(3,10,5)) # changed to show that order doesnt matter
asd %>%
mutate(prop = b/sum(b)) %>%
arrange(desc(a)) %>%
mutate(lab.ypos = cumsum(prop) - 0.5*prop) %>%
ggplot(aes(x = "", y = prop, fill = a)) +
geom_bar(width = 1, stat = "identity", color = "white") +
coord_polar("y", start = 0, clip = "off")+
geom_segment(aes(x = 1, y = lab.ypos, xend = 2, yend = lab.ypos, colour = a),
size = 1) +
geom_label(aes(y = lab.ypos, label = paste(a, scales::percent(prop))),
x = 2,
size = 5,
color = "white") +
theme_void() +
theme(legend.position = "none")
For the record: don't use pie chart.
There is a reason why doing a pie chart is complicated: you are not supposed to use them.
Bar charts are always better.

X axis and right box in stacked bars

In a plot like this
library(ggplot2)
df <- data.frame(class = c("a","b","a","b"), date = c(2009,2009,2010,2010), volume=c(1,1,2,0))
df <- df %>% group_by(date) %>% mutate(volumep = 100 * volume/sum(volume))
ggplot(df, aes(x = date, y = volumep, fill = class, label = volumep)) +
geom_bar(stat = "identity") +
geom_text(size = 3, position = position_stack(vjust = 0.5)) + coord_flip()
How is it possible to increase the text in the boxes in the right (class) and how to make the x axis have 0, 25, 50 and 100 values?
To answer the question, just adjust the involved aesthetics, y and size.
ggplot(df, aes(x = date, y = 100*volume, fill = class, label = volume)) +
geom_bar(stat = "identity") +
geom_text(size = c(3, 3, 5, 5), position = position_stack(vjust = 0.5)) +
coord_flip() +
ylab("volume")
Another option is to mutate the values of volume first. In this case, there would be no need to manually set the y axis label.
After the question's edit, the code is now as follows.
library(ggplot2)
library(dplyr)
df %>%
group_by(date) %>%
mutate(volume = 100*volume/sum(volume)) %>%
ggplot(aes(x = date, y = volume, fill = class, label = volume)) +
geom_bar(stat = "identity") +
geom_text(size = c(3, 3, 5, 5), position = position_stack(vjust = 0.5)) +
coord_flip()
ggplot(df, aes(x = date, y = volumnep, fill = class, label = volumnep)) +
geom_bar(stat = "identity") +
geom_text(size = 3, position = position_stack(vjust = 0.5)) +
coord_flip() +
theme(legend.title=element_text(size=22),
legend.text=element_text(size=22)) +
scale_y_continuous(breaks=c(0,25, 50, 100))
Edit:
I'd suggest recasting date as a factor:
ggplot(df, aes(x = factor(date), y = volumnep, fill = class, label = volumnep)) +
geom_bar(stat = "identity") +
geom_text(size = 3, position = position_stack(vjust = 0.5)) +
coord_flip() +
theme(legend.title=element_text(size=22),
legend.text=element_text(size=22)) +
scale_y_continuous(breaks=c(0,25, 50, 100)) +
labs(y="date")

ggplot add text to the center of a donut chart in R

I am working on a donut chart using ggplot2, but I need the center of the plot to contain text.
Here's sample data (found from this site: https://www.datanovia.com/en/blog/how-to-create-a-pie-chart-in-r-using-ggplot2/):
library(dplyr)
count.data <- data.frame(
class = c("1st", "2nd", "3rd", "Crew"),
n = c(325, 285, 706, 885),
prop = c(14.8, 12.9, 32.1, 40.2)
)
count.data <- count.data %>%
arrange(desc(class)) %>%
mutate(lab.ypos = cumsum(prop) - 0.5*prop)
count.data
I then modified their code to get this donut chart:
library(ggplot2)
library(dplyr)
mycols <- c("#0073C2FF", "#EFC000FF", "#868686FF", "#CD534CFF")
ggplot(count.data, aes(x = 2, y = prop, fill = class)) +
geom_bar(stat = "identity", color = "white") +
coord_polar(theta = "y", start = 0)+
geom_text(aes(y = lab.ypos, label = paste0("n = ", n, ", \n", prop, "%")), color = "white")+
scale_fill_manual(values = mycols) +
theme_void() +
xlim(.5, 2.5)
The plot looks like this:
It is exactly what I want except I need the center of the donut to have the proportion from a variable. In this case, I want the center to say 40.2% (the prop of crew, in this example).
How do I do this?
Edit
Used annotate as suggested by #aosmith and made it a direct call to crew.
like this?
ggplot(count.data, aes(x = 2, y = prop, fill = class)) +
geom_bar(stat = "identity", color = "white") +
coord_polar(theta = "y", start = 0)+
geom_text(aes(y = lab.ypos, label = paste0("n = ", n, ", \n", prop, "%")), color = "white")+
scale_fill_manual(values = mycols) +
theme_void() +
xlim(.5, 2.5) +
annotate(geom = 'text', x = 0.5, y = 0, label = paste0(count.data$prop[count.data$class == 'Crew'], "%"))

stacked bar *bringing labels to the graph *

I'm plotting a stacked bar graph and use geom_text to insert the value and name of each stack. The problem is some stacks are very small/narrow, so that the text of two stacks overlap each other and hence is not very readable. How can I modify the code to solve this issue.
Type<-c("ddddddddddd","ddddddddddd","bbbbbbbbbbbbb","ddddddddddd","eeeeeeeeeeeeee","bbbbbbbbbbbbb","ddddddddddd","bbbbbbbbbbbbb","ddddddddddd",
"eeeeeeeeeeeeee","mmmmmmmmmmmmmmmmmmm","bbbbbbbbbbbbb","ddddddddddd","bbbbbbbbbbbbb","eeeeeeeeeeeeee")
Category<-c("mmmmm","mmmmm","gggggggggggggggggg","ffffffffffff","ffffffffffff","ffffffffffff","sanddddddddd","sanddddddddd","yyyyyyyyyyy",
"yyyyyyyyyyy","yyyyyyyyyyy","sssssssssssssss","sssssssssssssss","sssssssssssssss","ttttttttttttt")
Frequency<-c(4,1,30,7,127,11,1,1,6,9,1,200,3,4,5)
Data <- data.frame(Type, Category, Frequency)
p <- ggplot(Data, aes(x = Type, y = Frequency)) +
geom_bar(aes(fill = Category), stat="identity", show.legend = FALSE) +
geom_text(aes(label = Frequency), size = 3) +
geom_text(aes(label = Category), size = 3)
Considering your data, a facetted plot might be a better approach:
# summarise your data
library(dplyr)
d1 <- Data %>%
mutate_each(funs(substr(.,1,2)),Type,Category) %>%
group_by(Type,Category) %>%
summarise(Freq = sum(Frequency)) %>%
mutate(lbl = paste(Category,Freq)) # create a label by pasting the 'Category' and the 'Freq' variables together
# plot
ggplot(d1, aes(x = Category, y = Freq, fill = Category)) +
geom_bar(stat="identity", width = 0.7, position = position_dodge(0.8)) +
geom_text(aes(label = lbl), angle = 90, size = 5, hjust = -0.1, position = position_dodge(0.8)) +
scale_y_continuous(limits = c(0,240)) +
guides(fill = FALSE) +
facet_grid(.~Type, scales = "free", space = "free") +
theme_bw(base_size = 14)
which gives:
In the above plot I shortened the labels on purpose. If you don't want to do that, you could consider this:
d2 <- Data %>%
group_by(Type,Category) %>%
summarise(Freq = sum(Frequency)) %>%
mutate(lbl = paste(Category,Freq))
ggplot(d2, aes(x = Category, y = Freq, fill = Category)) +
geom_bar(stat="identity", width = 0.7, position = position_dodge(0.8)) +
geom_text(aes(y = 5, label = lbl), alpha = 0.6, angle = 90, size = 5, hjust = 0, position = position_dodge(0.8)) +
scale_y_continuous(limits = c(0,240)) +
guides(fill = FALSE) +
facet_grid(.~Type, scales = "free", space = "free") +
theme_bw(base_size = 14) +
theme(axis.text.x = element_blank(),
axis.ticks.x = element_blank())
which gives:

Resources