Reputation: 177
I've run the following code and get the following plot. How do I manipulate the spacing between the numbers per stacked plot so it becomes readable?
ggplot(data=dat, aes(x=SU,fill=factor(SCIENTIFIC_NAME)))+
geom_bar(width=0.5)+xlab("Sampling Unit (SU)")+
ylab("Count")+labs(fill="SCIENTIFIC NAME")+
ggtitle("Inventory per sampling unit (SU) by species")+
geom_text(stat='count', aes(label=..count..), vjust=-1)+
scale_x_discrete(breaks=c(1,2,3,4,5,6,7,8,10,11,15))
Upvotes: 1
Views: 202
Reputation: 2026
You can plot the bars and labels separately, and then a line segment to join them. I also handled overlapping labels in a simple way.
library(ggplot2)
library(dplyr)
df <- data.frame(group = c("A","A","A",
"B","B","B"),
sector = c("x","y","z",
"x","y","z"),
value = c(10,1,
2,1,2,100))
df <- df %>% # calculate label position
group_by(group) %>% # for each bar
arrange(desc(sector)) %>% # from bottom to top
mutate(
midy = cumsum(value) - value / 2, # base label position
dmidy = diff(c(0, midy)), # gaps between labels (and axis)
dmidy2 = pmax(dmidy, 10), # apply minimum label spacing
labely = cumsum(dmidy2) # final label position
) %>% #
arrange(group, sector) # useful for debugging
ggplot(data = df) +
geom_col(mapping = aes(x = group, y = value, fill = sector), width = 0.5) + # plot the bar
geom_text(mapping = aes(x = group, y = labely, label = value), nudge_x = 0.5) + # plot the label
geom_segment(mapping = aes(x = group, y = midy, xend = as.integer(group) + 0.4, yend = labely)) # plot the line
Created on 2020-07-06 by the reprex package (v0.3.0)
Upvotes: 0
Reputation: 6769
I think @Duck's solution is great. As some boxes are very small in OP, you may also want to try ggrepel
to push the numbers away from each other.
library(ggplot2)
library(ggrepel)
#Data
data <- data.frame(group = c("A","A","A",
"B","B","B"),
sector = c("x","y","z",
"x","y","z"),
value = c(10,1,
2,1,2,100))
ggplot(data = data, aes(x = group, y = value, fill = sector)) +
geom_col() +
geom_text_repel(aes(label = value),
position = position_stack(vjust = .5))
Upvotes: 1
Reputation: 39603
As long as data is not included, I hope this exercise with example data helps you:
library(ggplot2)
#Data
data <- data.frame(group = c("A","A","A",
"B","B","B"),
sector = c("x","y","z",
"x","y","z"),
value = c(10,20,70,
30,20,50))
#Plot
ggplot(data = data, aes(x = group, y = value, fill = sector)) +
geom_col() +
geom_text(aes(label = value),
position = position_stack(vjust = .5))
Upvotes: 1