Consider the figure below:
This question is about how to keep all the value labels in the stacked bars in one decimal place, to allow for consistency. Thus, to present -1, 2 and 5 as -1.0, 2.0 and 5.0 in line with others. Here is an example data
df <- data.frame(group=c("satisfied", "satisfied",
"unsatisfied","unsatisfied",
"satisfied", "satisfied",
"unsatisfied","unsatisfied"
),
cost=c("low","high","low","high",
"low","high","low","high"),
treatment=c("treated","treated","treated","treated",
"untreated","untreated",
"untreated","untreated") ,
value=c(2.3,8.7,5.0,3.1,9.4,3.1,2.0,-1.0))
and the code for generating the figure is
#REORDER
df$group <- factor(df$group, levels = c("satisfied",
"unsatisfied"))
ggplot(data=df,aes(y = value, x = group, fill = cost)) +
geom_bar(stat="identity",position='stack') +
ylab("Y label") +
theme(legend.direction = "horizontal",legend.position = "bottom",
legend.spacing.x = unit(0.1, 'cm'))+
theme(legend.title=element_blank())+
geom_text(aes(label = ifelse(value !=0, value, "")),
position = position_stack(vjust=0.5))+
facet_grid( ~ treatment)
Following how to put exact number of decimal places on label ggplot bar chart I attempted to resolve this by introducing
sprintf("%0.1f", round(value, digits = 2))
into the ggplot function, but this does not produce the desired output. I greatly appreciate any help on this.
The problem is that you rounded (and thus converted to character
, losing numeric information) before using sprintf
. To format numbers, you need to give sprintf
numbers, not strings. It will take care of the rounding itself. Try this:
label = ifelse(value !=0, sprintf("%0.1f", value), "")
Making the whole code:
ggplot(data = df, aes(y = value, x = group, fill = cost)) +
geom_bar(stat = "identity", position = 'stack') +
ylab("Y label") +
theme(
legend.direction = "horizontal",
legend.position = "bottom",
legend.spacing.x = unit(0.1, 'cm')
) +
theme(legend.title = element_blank()) +
geom_text(aes(label = ifelse(value !=0, sprintf("%0.1f", value), "")),
position = position_stack(vjust = 0.5)) +
facet_grid(~ treatment)
The above is a little weird because of the ifelse
. A more standard ggplot2
solution would have you get rid of the 0s another way - maybe filter it out before plotting, give data = filter(df, y != 0)
to ggplot()
. Then you can use the scales
functions
label = scales::label_number(accuracy = 0.1)(value)
Making the whole code as below, for the same result:
ggplot(data = dplyr::filter(df, value != 0), aes(y = value, x = group, fill = cost)) +
geom_bar(stat = "identity", position = 'stack') +
ylab("Y label") +
theme(
legend.direction = "horizontal",
legend.position = "bottom",
legend.spacing.x = unit(0.1, 'cm')
) +
theme(legend.title = element_blank()) +
geom_text(aes(label = scales::label_number(accuracy = 0.1)(value)),
position = position_stack(vjust = 0.5)) +
facet_grid(~ treatment)