I have a following problem. I want increase a padding bettween the text and the bar. But at same time, the value of text must be in the box of ggplot2 device.
Reproducible examples:
diamonds %>%
group_by(color) %>%
count() %>%
ggplot(aes(color, y = n)) +
geom_bar(stat = "identity") +
geom_text(
aes(label = n),
vjust = 0.5,
hjust = "inward") +
coord_flip()
Because you flipped coordinates it looks like your hjust and vjust calls were applied incorrectly. With this in mind, I only adjusted the text horizontally and I expanded the limits to fit the label for G, which would otherwise be cut off by the limits of the graph.
diamonds %>%
group_by(color) %>%
count() %>%
ggplot(aes(color, y = n)) +
geom_bar(stat = "identity") +
geom_text(aes(label = n),
hjust = -.5) +
coord_flip() +
expand_limits(y = 12000)
Or, if you want the text labels to be within the bars you can use the following.
diamonds %>%
group_by(color) %>%
count() %>%
ggplot(aes(color, y = n)) +
geom_bar(stat = "identity") +
geom_text(aes(label = n),
hjust = 1.5) +
coord_flip()
Related
Below is my code to generate a horizontal bar chart. The percentage are not in order. I would like percentage from 0 to 100%.
df %>%
dplyr::group_by(Site_name) %>%
dplyr::summarise(n = sum(Race %in% "Missing"), perc = paste0(round(n/n()*100),"%")) %>%
ggplot(aes(Site_name, perc)) + geom_col(position = 'dodge', fill = "#0000FF", stat="identity") +
coord_flip() + geom_text(aes(label=perc), vjust=0, color="black",
position = position_dodge(0.9), size=3.5)
The graph that is generated is below. But I want percentage axis in increase order from 0 to 100.
I think you're looking for dplyr::arrange. Documentation here
df %>%
dplyr::group_by(Site_name) %>%
dplyr::summarise(n = sum(Race %in% "Missing"), perc = round(n/n()*100)) %>%
dplyr::arrange(perc) %>%
ggplot(aes(Site_name, perc)) +
geom_col(position = 'dodge', fill = "#0000FF", stat="identity") +
coord_flip() +
geom_text(
aes(label=perc),
vjust=0,
color="black",
position = position_dodge(0.9),
size=3.5
)
I am using ggplot2 to make a bar plot that is grouped by one variable and reported in shares.
I would like the percentages to instead be a percentage of the grouping variable rather than a percentage of the whole data set.
For example,
library(ggplot2)
library(tidyverse)
ggplot(mtcars, aes(x = as.factor(cyl),
y = (..count..) / sum(..count..),
fill = as.factor(gear))) +
geom_bar(position = position_dodge(preserve = "single")) +
geom_text(aes(label = scales::percent((..count..)/sum(..count..)),
y= ((..count..)/sum(..count..))), stat="count") +
theme(legend.position = "none")
Produces this output:
I'd like the percentages (and bar heights) to reflect the "within cyl" proportion rather than share across the entire sample. Is this possible? Would this involve a stat argument?
As an aside, if its possible to similarly position the geom_text call over the relevant bars that would be ideal. Any guidance would be appreciated.
Here is one way :
library(dplyr)
library(ggplot2)
mtcars %>%
count(cyl, gear) %>%
group_by(cyl) %>%
mutate(prop = prop.table(n) * 100) %>%
ggplot() + aes(cyl, prop, fill = factor(gear),
label = paste0(round(prop, 2), '%')) +
geom_col(position = "dodge") +
geom_text(position = position_dodge(width = 2), vjust = -0.5, hjust = 0.5)
I am trying to make this graph look better, and I'm stuck with the labels (the numbers in this case). How can I make them to show on the top of their correspondent bar? Notice it is a facet_grid.
I have the following code and the output:
ggplot(articles_europaoccidental_sex_count_unique_group, aes(Country, percentage)) + geom_bar(stat = "identity", position = "dodge", aes(fill=Gender)) +
facet_grid(~Propuesta) + geom_text(aes(label = round(percentage, 2)), position = position_dodge(width = 0.9), vjust = -1)
Thanks!
You are almost there, just you need to move aes(fill=Gender) to inside ggplot
library(tidyverse)
#Reproducible data set
test_mtcars <- mtcars %>% group_by(cyl,am, gear) %>% summarise(mean = mean(mpg))
ggplot(test_mtcars, aes(as.factor(cyl), mean, fill=as.factor(am))) + geom_bar(stat = "identity", position = "dodge") +
facet_grid(~gear) + geom_text(aes(label = round(mean, 2)), position = position_dodge(width = 0.9), vjust = -1)
Is there a way to add space between the labels on the top of the chart and the margin of a plot using ggplot's facet_grid. Below is a reproducible example.
library(dplyr)
library(ggplot2)
Titanic %>% as.data.frame() %>%
filter(Survived == "Yes") %>%
mutate(FreqSurvived = ifelse(Freq > 100, Freq*1e+04,Freq)) %>%
ggplot( aes(x = Age, y = FreqSurvived, fill = Sex)) +
geom_bar(stat = "identity", position = "dodge") +
facet_grid(Class ~ ., scales = "free") +
theme_bw() +
geom_text(aes(label = prettyNum(FreqSurvived,big.mark = ",")), vjust = 0, position = position_dodge(0.9), size = 2)
The resulting chart has the label of numbers right next to the border of the plot.
I wanted to add to #dww 's answer, but don't have enough reputation.
The expand option actually will allow you to add space only to the top of your graph. From the ?expand_scale help file:
# No space below the bars but 10% above them
ggplot(mtcars) +
geom_bar(aes(x = factor(cyl))) +
scale_y_continuous(expand = expand_scale(mult = c(0, .1)))
One simple way is to use the expand argument of scale_y_continuous:
dt = Titanic %>% as.data.frame() %>%
filter(Survived == "Yes") %>%
mutate(FreqSurvived = ifelse(Freq > 100, Freq*1e+04,Freq))
ggplot(dt, aes(x = Age, y = FreqSurvived, fill = Sex)) +
geom_bar(stat = "identity", position = "dodge") +
facet_grid(Class ~ ., scales = "free") +
theme_bw() +
geom_text(aes(label = prettyNum(FreqSurvived,big.mark = ",")),
vjust = 0, position = position_dodge(0.9), size = 2) +
scale_y_continuous(expand = c(0.1,0))
The downside of using expand is that it will add space both above and below the bars. An alternative is to plot some invisible data on the graph at a height above the bars, which will force ggplt to expand the axis ranges to accomodate this dummy data. Here I add some invisible bars whose height is 1.2* the actual bars:
Titanic %>% as.data.frame() %>%
filter(Survived == "Yes") %>%
mutate(FreqSurvived = ifelse(Freq > 100, Freq*1e+04,Freq)) %>%
ggplot( aes(x = Age, y = FreqSurvived, fill = Sex)) +
geom_bar(aes(y = FreqSurvived*1.2), stat = "identity",
position = "dodge", fill=NA) +
geom_bar(stat = "identity", position = "dodge") +
facet_grid(Class ~ ., scales = "free") +
theme_bw() +
geom_text(aes(label = prettyNum(FreqSurvived,big.mark = ",")),
vjust = 0,
position = position_dodge(0.9), size = 2)
How does one plot "filled" bars with counts labels using ggplot2?
I'm able to do this for "stacked" bars. But I'm very confused otherwise.
Here is a reproducible example using dplyr and the mpg dataset
library(ggplot)
library(dplyr)
mpg_summ <- mpg %>%
group_by(class, drv) %>%
summarise(freq = n()) %>%
ungroup() %>%
mutate(total = sum(freq),
prop = freq/total)
g <- ggplot(mpg_summ, aes(x = class, y = prop, group = drv))
g + geom_col(aes(fill = drv)) +
geom_text(aes(label = freq), position = position_stack(vjust = .5))
But if I try to plot counts for filled bars it does not work
g <- ggplot(mpg_summ, aes(x=class, fill=drv))
g + stat_count(aes(y = (..count..)/sum(..count..)), geom="bar", position="fill") +
scale_y_continuous(labels = percent_format())
Further, if I try:
g <- ggplot(mpg_summ, aes(x=class, fill=drv))
g + geom_bar(aes(y = freq), position="fill") +
geom_text(aes(label = freq), position = "fill") +
scale_y_continuous(labels = percent_format())
I get:
Error: stat_count() must not be used with a y aesthetic.
I missed the fill portion from the last question. This should get you there:
library(ggplot2)
library(dplyr)
mpg_summ <- mpg %>%
group_by(class, drv) %>%
summarise(freq = n()) %>%
ungroup() %>%
mutate(total = sum(freq),
prop = freq/total)
g <- ggplot(mpg_summ, aes(x = class, y = prop, group = drv))
g + geom_col(aes(fill = drv), position = 'fill') +
geom_text(aes(label = freq), position = position_fill(vjust = .5))