How to align text on clustered bar chart in ggplot2? - r

I'm trying to align the percent frequency of each bar in my clustered bar chart. Right now, my chart looks like this:
Here's the code as well:
ggplot(graph_data, aes(x, Freq)) +
geom_bar(aes(fill = Pref), position = 'dodge', stat = 'identity') +
geom_text(aes(label = sprintf("%.0f%%", round(Freq/sum(Freq) * 100))),
hjust = -0.25) +
labs(list(x = attr(graph_data, 'seg_label'),
y = 'Frequency',
title = paste('Q:', attr(graph_data, 'question')))) +
scale_y_continuous(limits = c(0, 1.2 * max(graph_data$Freq))) +
guides(fill = F) +
coord_flip() +
annotate("text", x = Inf, y = Inf,
label = paste0("N = ", sum(graph_data$Freq)),
hjust = 1.5, vjust = 1.5)
I think the issue can be solved on this snippet of code, but I'm not sure how:
geom_text(aes(label = sprintf("%.0f%%", round(Freq/sum(Freq) * 100))), hjust = -0.25)
Any help would be greatly appreciated!
Edit: Here's a sample of my data's structure as well:
df <- data.frame(x = rep(c('1824', '2534', '3544'), 3),
Pref = rep(c('low', 'neutral', 'high')),
Freq = 1:9 * 10)

As mentioned in the comments I think this is a duplicate of Position geom_text on dodged barplot.
But I did it now, so I'll include the code.
ggplot(df, aes(x, Freq, fill = Pref)) +
geom_bar(position = 'dodge', stat = 'identity') +
geom_text(aes(label = sprintf("%.0f%%", round(Freq/sum(Freq) * 100))),
position = position_dodge(width = 0.9), hjust = -0.25) +
labs(list(x = attr(df, 'seg_label'),
y = 'Frequency',
title = paste('Q:', attr(df, 'question')))) +
scale_y_continuous(limits = c(0, 1.2 * max(df$Freq))) +
guides(fill = F) +
coord_flip()
You need to put fill in the original aes so the that geom_text knows which label to dodge by which amount.

Related

how to have the legend inside a grouped bar graph in R ggplot?

So my legend here is village which has (Chirodzo, God, Ruaca). How to remove the legend and display it inside the bars; for instance inside the bar for chirodzo, I want chirodzo written inside?
ggplot(data = interviews_plotting, aes(x = respondent_wall_type, fill = village)) +
geom_bar(position = "fill")
Source is here https://mq-software-carpentry.github.io/r-ggplot-extension/02-categorical-data/index.html
ggplot(data = interviews_plotting, aes(x = respondent_wall_type, fill = village)) +
geom_bar(position = "fill")
To label your bars with the fill category and getting rid of the legend you could use geom_text like so:
Using mtcars as example data:
library(ggplot2)
ggplot(data = mtcars, aes(x = am, fill = factor(cyl))) +
geom_bar(position = "fill") +
geom_text(aes(label = cyl), stat = "count", position = position_fill(vjust = 0.5)) +
guides(fill = "none")
From your comments, it sounds like you are looking for something like this:
library(ggplot2)
ggplot(interviews_plotting, aes(x = respondent_wall_type, fill = village)) +
geom_bar(position = position_dodge()) +
geom_text(stat = 'count',
aes(y = stat(count)/2, label = village, group = village),
position = position_dodge(width = 1), angle = 90) +
guides(fill = guide_none())
Or, if you want to get a bit more sophisticated with your label placement and theme choices:
library(ggplot2)
ggplot(interviews_plotting, aes(x = respondent_wall_type, fill = village)) +
geom_bar(position = position_dodge(width = 0.9), width = 0.8) +
geom_text(stat = 'count', size = 6,
aes(y = ifelse(stat(count) > 2, stat(count)/2, stat(count)),
label = village, group = village,
hjust = ifelse(stat(count) > 2, 0.5, -0.2)),
position = position_dodge(width = 0.9), angle = 90) +
labs(x = 'Wall type', y = 'Count') +
theme_minimal(base_size = 16) +
scale_fill_brewer(palette = 'Set2', guide = 'none')
Data used
interviews_plotting <- read.csv(paste0("https://raw.githubusercontent.com/",
"humburg/r-ggplot-project/master/",
"data_output/interviews_plotting.csv"))

geom_text with rounded percentage numbers on a bar graph?

I am trying to achieve a bar graph with percentages shown, but can not round them down.
In this variant the percentages are shown, but I am not able to round them
ggplot(data=true_dizzy, aes(x = reorder(factor(ICD_subgroup_new), ICD_subgroup_new, length),
y = prop.table(stat(count)),
label = scales::percent(prop.table(stat(count))))) +
geom_bar() +
coord_flip() +
geom_text(stat = "count", position = position_dodge(.9), hjust = 0, size = 3) +
scale_y_continuous(label = scales::percent) +
labs(y = c(""), x = c(""), title = c("Subgroups of Dizzy Patients (%")) +
theme_bw()
and in this variant there are no percent signs behind the numbers
ggplot(data=true_dizzy, aes(x = reorder(factor(ICD_subgroup_new), ICD_subgroup_new, length),
y = prop.table(stat(count)),
label = scales::percent(prop.table(stat(count))))) +
geom_bar() +
coord_flip() +
geom_text(stat = "count", aes(label = round(x = (..count../sum(..count..))*100, digits = 1), hjust = 0),
position = position_dodge(.9), hjust = 0, size = 3) +
scale_y_continuous(label = scales::percent) +
labs(y = c(""), x = c(""), title = c("Subgroups of Dizzy Patients (%")) +
theme_bw()
I know the problem is in the geom_text line, but i cant seem to figure it out.

Breaking y-axis in ggplot2 with geom_bar

I'm having a hard time dealing with this plot.
The height of values in ANI>96 making it hard to read the red and blue percentage text.
I failed to break the y-axis by looking at answers from other posts in StackOverflow.
Any suggestions?
Thanks.
library(data.table)
library(ggplot2)
dt <- data.table("ANI"= sort(c(seq(79,99),seq(79,99))), "n_pairs" = c(5, 55, 13, 4366, 6692, 59568, 382873, 397996, 1104955, 282915,
759579, 261170, 312989, 48423, 120574, 187685, 353819, 79468, 218039, 66314, 41826, 57668, 112960, 81652, 28613,
64656, 21939, 113656, 170578, 238967, 610234, 231853, 1412303, 5567, 4607268, 5, 14631942, 0, 17054678, 0, 3503846, 0),
"same/diff" = rep(c("yes","no"), 21))
for (i in 1:nrow(dt)) {
if (i%%2==0) {
next
}
total <- dt$n_pairs[i] + dt$n_pairs[i+1]
dt$total[i] <- total
dt$percent[i] <- paste0(round(dt$n_pairs[i]/total *100,2), "%")
dt$total[i+1] <- total
dt$percent[i+1] <- paste0(round(dt$n_pairs[i+1]/total *100,2), "%")
}
ggplot(data=dt, aes(x=ANI, y=n_pairs, fill=`same/diff`)) +
geom_text(aes(label=percent), position=position_dodge(width=0.9), hjust=0.75, vjust=-0.25) +
geom_bar(stat="identity") + scale_x_continuous(breaks = dt$ANI) +
labs(x ="ANI", y = "Number of pairs", fill = "Share one common species taxonomy?") +
theme_classic() + theme(legend.position="bottom")
Here is the list of major changes I made:
I reduced the y axis by zooming into the chart with coord_cartesian (which is called by coord_flip).
coord_flip shouuld also improve the readability of the chart by switching x and y. I don't know if the switch is a desirable output for you.
Also now position_dodge, works as expected: two bars next to each other with the labels on top (on the left in this case).
I set geom_bar before geom_text so that the text is always in front of the bars in the chart.
I set scale_y_continuous to change the labels of the y axis (in the chart the x axis because of the switch) to improve the readability of the zeros.
ggplot(data=dt, aes(x = ANI, y = n_pairs, fill = `same/diff`)) +
geom_bar(stat = "identity", position = position_dodge2(width = 1), width = 0.8) +
geom_text(aes(label = percent), position = position_dodge2(width = 1), hjust = 0, size = 3) +
scale_x_continuous(breaks = dt$ANI) +
scale_y_continuous(labels = scales::comma) +
labs(x ="ANI", y = "Number of pairs", fill = "Share one common species taxonomy?") +
theme_classic() +
theme(legend.position = "bottom") +
coord_flip(ylim = c(0, 2e6))
EDIT
Like this columns and labels are stacked but labels never overlap.
ggplot(data=dt, aes(x = ANI, y = n_pairs, fill = `same/diff`)) +
geom_bar(stat = "identity", width = 0.8) +
geom_text(aes(label = percent,
hjust = ifelse(`same/diff` == "yes", 1, 0)),
position = "stack", size = 3) +
scale_x_continuous(breaks = dt$ANI) +
scale_y_continuous(labels = scales::comma) +
labs(x ="ANI", y = "Number of pairs", fill = "Share one common species taxonomy?") +
theme_classic() +
theme(legend.position = "bottom") +
coord_flip(ylim = c(0, 2e6))
Alternatively, you can avoid labels overlapping with check_overlap = TRUE, but sometimes one of the labels will not be shown.
ggplot(data=dt, aes(x = ANI, y = n_pairs, fill = `same/diff`)) +
geom_bar(stat = "identity", width = 0.8) +
geom_text(aes(label = percent), hjust = 1, position = "stack", size = 3, check_overlap = TRUE) +
scale_x_continuous(breaks = dt$ANI) +
scale_y_continuous(labels = scales::comma) +
labs(x ="ANI", y = "Number of pairs", fill = "Share one common species taxonomy?") +
theme_classic() +
theme(legend.position = "bottom") +
coord_flip(ylim = c(0, 2e6))

Adding text labels over barplot with ggplotly in R

I have the following dataframe in R
DF_1<-data.frame("ID"=c("A_1", "A_2"), 'Sum'= c(2500,12500), "RR"=
c(95,95), "CC"= c(50,50), "nn"=c(4,4), "DP"= c(12.5,100))
I have created the following barplot with text written in the barplot as follows
p2<-ggplot(data = DF_1, mapping = aes(x = ID, y = DP,
fill=str_wrap(ID,10))) + geom_bar(stat = 'identity', width = .35, position
= "dodge")+ geom_text(aes(label=RR) , position = position_dodge(0.9),vjust
= 2,check_overlap = TRUE)+geom_text(aes(label=CC) , position = postion_dodge(0.9),vjust = 4,check_overlap = TRUE)+ geom_text(aes(label=nn) , position = position_dodge(0.9),vjust = 6,check_overlap = TRUE)+ labs(fill = "LEGEND")+labs(x = "XLabels", y= "DPP")+theme(legend.key.height = unit( 2 ,"cm"))+theme(axis.text.x=element_blank())+ggtitle("DPPCHART")+ theme(plot.title = element_text(hjust = 0.5))
In the plot so generated the three text labels are generated clearly on the barplot. The next step is to make dynamic ticks work
p<-ggplotly(p, dynamicticks=T)
Now the three text labels overlap each other.
Is there a way to retain the text labels separately when using ggplotly.
You can use HTML directly inside the labels like this to remove the overlap:
library(stringr)
library(ggplot2)
library(plotly)
DF_1 <- data.frame("ID"=c("A_1", "A_2"), 'Sum'= c(2500,12500),
"RR"= c(95,95), "CC"= c(50,50), "nn"=c(4,4), "DP"= c(12.5,100))
p <- ggplot(data = DF_1, mapping = aes(x = ID, y = DP,fill=str_wrap(ID,10))) +
geom_bar(stat = 'identity', width = .35, position = "dodge") +
geom_text(aes(label=paste0(RR, "<br>", CC, "<br>", nn)) ,
position = position_dodge(0.9), vjust = 2, check_overlap = TRUE) +
labs(fill = "LEGEND") + labs(x = "XLabels", y= "DPP") +
theme(legend.key.height = unit( 2 ,"cm")) +
theme(axis.text.x=element_blank()) +
ggtitle("DPPCHART") +
theme(plot.title = element_text(hjust = 0.5)) +
scale_y_continuous(limits = c(0,110))
ggplotly(p) # can use with or without dynamicTicks=TRUE
Output is:

Construction of multi-bar graph

How to construct a graph like on the attached link
I have no idea how to put and move the bars in ggplot2
Thank you in advance for your help
For ease of data transfer
data <- data.frame(klm=c(1L,2L,3L),
year=c(rep(2000,3),rep(2016,3)),
Category1=c(c(1313,1057,981),c(1456,1200,1124)),
Category2=c(c(1661,1057,981),c(1827,1444,1400)))
data$klm <- factor(data$klm, levels=1:3, labels=c("Belgium", "Netherlands","Germany"))
data$rok <- factor(data$year,levels=c(2000,2016))
ggplot(data, aes(x = klm))
+ geom_bar(aes(y = Category1[1:3]))
+ geom_bar(aes(y = Category1[4:6]),position = "dodge")
+ geom_bar(aes(y = Category2[1:3]))
+ geom_bar(aes(y = Category2[4:6]),position = "dodge")
I'm starting, I do not know ggplot well
Will help someone improve it visually
data <- data.frame(klm=c(1L,2L,3L),
year=c(rep(2000,3),rep(2016,3)),
Category1=c(c(1313,1057,981),c(1456,1200,1124)),
Category2=c(c(1661,1257,1301),c(1827,1444,1600)))
data$klm <- factor(data$klm, levels=1:3, labels=c("Belgium", "Netherlands","Germany"))
data$year <- factor(data$year,levels=c(2000,2016))
Średnia=
ggplot(data=data, aes(x=klm, y=Category2, fill=year)) +
geom_bar(stat="identity", position=position_dodge(),colour="black")+
scale_fill_manual(values = c("blue", "red"))+
geom_text(aes(y = Category2,label = format(Category2,big.mark = " ")),position = position_dodge(width = 1),vjust = -0.5, hjust = 0.5, cex = 3)
Średnia+
geom_bar(data=data, aes(x=klm, y=Category1, fill=year),stat="identity", width = 0.5,position=position_dodge(), colour="black")+
geom_text(aes(y = Category1,label = format(Category1,big.mark = " ")),position = position_dodge(width = 1),vjust = -0.5, hjust = 0.5, cex = 3)
I do not know how to change the colors of the second bars and how to make the right legend
Thank you for the tips

Resources