r annotate values above geometric bars - r

Consider this sample data.
df <- data.frame(
x = factor(c(1, 1, 2, 2)),
y = c(.1, .3, .2, .1),
grp = c("a", "b", "a", "b")
)
Now I create the graph using ggplot, and annotate it using geom_text()
ggplot(data = df, aes(x, y, fill = grp, label = y)) +
geom_bar(stat = "identity", position = "dodge") +
scale_y_continuous(limits=c(0,1)) +
geom_text(position = position_dodge(0.9))
How do I specify that all the text values align perfectly horizontal at the top of the graph window?

You can specify the aes(y=...) in geom_text. So, for the numbers at the top of the graph window you'll have
ggplot(data = df, aes(x, y, fill = grp, label = y)) +
geom_bar(stat = "identity", position = "dodge") +
geom_text(aes(y=Inf), position = position_dodge(0.9))
And you may want to chuck in a + ylim(0, 4) to expand the plot area.
To match the edited question:
ggplot(data = df, aes(x, y, fill = grp, label = y)) +
geom_bar(stat = "identity", position = "dodge") +
scale_y_continuous(limits=c(0,1)) +
geom_text(aes(y=0.9), position = position_dodge(0.9)) ## can specify any y=.. value

Related

Make value labels all same height on GGPLOT2?

I would like to make all of my value labels to be at the same height above the bars on ggplot2. How can I do this?
p <- ggplot(figure_df, aes(x=event_type, y=fraction)) +
geom_bar(aes(fill=factor(method)), position=position_dodge(width=0.9), stat="identity") +
facet_grid(~event_time, switch="x") +
theme(axis.text.x = element_text(angle = 45,hjust = 1)) +
geom_text(aes(label=ifelse(method == 'THRIVE',round(pval, 2)," ")))
It's always best to make your questions reproducible. Check it out: making R reproducible questions.
In lieu of the data I don't have, I made some to answer your question. To set a position at the same height for all labels, you can set y in geom_text to a static number.
Here's an example:
set.seed(3523)
df1 = data.frame(coloring = rep(LETTERS[1:2], 4),
x = rep(LETTERS[1:4], each = 2),
y = runif(8, 10, 29))
ggplot(df1, aes(x = x, y = y, fill = coloring)) +
geom_col(position = position_dodge(.9)) +
geom_text(aes(y = 10, label = round(y, 1)),
position = position_dodge(.9))
You said you wanted the values above the bars. You can set it to a known value or you can use the data to set a singular static value, like this:
ggplot(df1, aes(x = x, y = y, fill = coloring)) +
geom_col(position = position_dodge(.9)) +
geom_text(aes(y = max(y) + 1, label = round(y, 1)),
position = position_dodge(.9))
If you didn't want them at the same height, but you wanted them at the same distance from the bars, you can do that in a variety of different ways. Here is one method.
ggplot(df1, aes(x = x, y = y, fill = coloring)) +
geom_col(position = position_dodge(.9)) +
geom_text(aes(y = y + 1, label = round(y, 1)),
position = position_dodge(.9))

gghighlight (R): Labeling bar charts

Alright, after a long silent read along, here's my first question. I am trying to add corresponding labels of unhighlighted items for a grouped barplot. When I insert gghighlight in front of the geom_text I get the following plot:
library(tidyverse)
library(gghighlight)
df <- data.frame (group = c("A", "A", "B", "B", "C", "C"),
value = c("value_1", "value_2","value_1", "value_2","value_1", "value_2"),
mean = c(1.331, 1.931, 3.231, 3.331, 4.631, 3.331)
)
ggplot(data = df, aes(x = group, y = mean, fill = value)) +
geom_bar(stat = "identity", position = "dodge") +
gghighlight(group != "B",
label_key = group
) +
geom_text(aes(label = round(mean, digits = 2)),
stat= "identity",
vjust = -.5,
position = position_dodge(width = .9)
)
If I move gghightlight behind the geom_text I get the following plot:
ggplot(data = df, aes(x = group, y = mean, fill = value)) +
geom_bar(stat = "identity", position = "dodge") +
geom_text(aes(label = round(mean, digits = 2)),
stat= "identity",
vjust = -.5,
position = position_dodge(width = .9)
) +
gghighlight(group != "B",
label_key = group)
Is there a way to label the unhighligthed bars like the highlighted ones?
Thanks in advance.
############## EDIT ###########
Besides graying out certain columns (see #TarJae's answer), there is also the possibility to make them transparent (essential parts are from this post: ggplot transparency on individual bar):
subset_df <- df %>%
mutate(alpha.adj = as.factor(ifelse(group != "B", 1, 0.6)))
ggplot(data = subset_df, aes(x = group, y = mean, fill = value, alpha=factor(alpha.adj))) +
geom_bar(stat = "identity", position = "dodge") +
geom_text(aes(label = round(mean, digits = 2)),
stat= "identity",
vjust = -.5,
position = position_dodge(width = .9)
) +
scale_alpha_manual(values = c("0.6"=0.6, "1"=1), guide='none')
[]
Are you looking for this?
This is a solution without using gghighlight package:
library(tidyverse)
subset_df <- df %>%
mutate(highlight = if_else(group != "B", mean, NA_real_))
ggplot(data = subset_df, aes(x = group, y = mean, group=value)) +
geom_col(fill = 'grey', alpha = 0.6, position = 'dodge') +
geom_col(aes(y = highlight, fill = value), position = 'dodge') +
geom_text(aes(group, label = round(mean, digits = 2)),
position = position_dodge(width = 1))
This is a solution with the gghighlight package and some limited hacky code.
When reading the vignette, I noticed that the author of the package "filters out" the data that are not highlighted. You can see that if you save your highlighted plot in p_h and then look at p_h$data, the values for group B have disappeared.
library(tidyverse)
library(gghighlight)
p_h <- ggplot(data = df, aes(x = group, y = mean, fill = value)) +
geom_bar(stat = "identity", position = "dodge") +
gghighlight(group != "B",
label_key = group) +
geom_text(aes(label = round(mean, digits = 2)),
stat= "identity",
vjust = -.5,
position = position_dodge(width = .9))
> p_h$data
group value mean
1 A value_1 1.331
2 A value_2 1.931
5 C value_1 4.631
6 C value_2 3.331
If we re-insert the data (after the call to gghighlight() has removed them), then geom_text() will be able to find the means for group B again.
One can "recover" the data and re-insert them with the following code:
### create a ggplot object with the original complete data
### you could check that with p_to_copy_data$data
p_to_copy_data <- ggplot(data = df)
### copy the complete data to your highlighted plot data section
p_h$data <- p_to_copy_data$data
p_h
This yields the following graph:

Why does the value of y increase in geom_bar(stat = "identity") for a stacked bar chart with a factor grouping?

In the following example, I think the height of the bars should be 500 and 45. Why are they both over 1000?
library(tidyverse)
dat <- tibble(
x = c(1, 1, 2, 2, 2),
grp = factor(c(0, 1, 0, 1, 2), levels = 0:2),
y = c(200, 300, 25, 15, 5)
)
ggplot(dat, aes(x = x, y = y, fill = grp)) +
geom_bar(stat = "identity") +
scale_y_log10(labels = scales::comma)
If you use position = "dodge", the y-axis values appear to be correct.
ggplot(dat, aes(x = x, y = y, fill = grp)) +
geom_bar(stat = "identity", position = "dodge") +
scale_y_log10(labels = scales::comma)
Any ideas where ggplot2 is getting its y-axis values in the first plot?

Continuous position scales with no effect on the spacing between the bar and the x axis in ggplot2 with R

I am designing a bar plot with ggplot2 package.
The only problem is that I cannot get rid of the space between the bars and the x-axis.
I know that this formula should resolve the problem:
scale_y_continuous(expand = c(0, 0)) function
But it seems that the element for the error bar is overwriting it and gives always this space.
here my code:
p<-ggplot(data=tableaumergectrlmut, aes(x=ID, y=meanNSAFbait, fill=Condition)) +
geom_bar(stat="identity", position=position_dodge())+
scale_y_continuous(expand = c(0,0))+
geom_errorbar(aes(ymin=meanNSAFbait-SDNSAFbait,
ymax=meanNSAFbait+SDNSAFbait, width=0.25), position=position_dodge(.9))
Using some example data to generate a plot that (I think) shows the problem you're having.
library(ggplot2)
df <- data.frame(val = c(10, 20, 100, 5), name = LETTERS[1:4])
ggplot(df, aes(x = name, y = val, fill = name)) +
geom_bar(stat = "identity")
There is a gap from the zero point on the y axis (bottom of the bars) and where the x axis labels are.
You can remove this using scale_y_discrete or scale_y_continuous, depending on the nature of your data, and setting expand to c(0,0):
ggplot(df, aes(x = name, y = val, fill = name)) +
geom_bar(stat = "identity") +
scale_y_discrete(expand = c(0,0)) +
scale_x_discrete(expand = c(0,0))
This gives the plot:
Note I've also removed the gap along the y axis, simply remove the scale_x_discrete line to add this gap back in.
Since error bars are an issue, here are a few examples:
ggplot(df, aes(x = name, y = val, fill = name)) +
geom_bar(stat = "identity") +
geom_errorbar(aes(ymin = val - 10,
ymax = val + 10))
You can use scale to remove the padding down to the error bar:
ggplot(df, aes(x = name, y = val, fill = name)) +
geom_bar(stat = "identity") +
geom_errorbar(aes(ymin = val - 10,
ymax = val + 10)) +
scale_y_continuous(expand = c(0,0))
Or you can use coord_cartesian to give a hard cutoff:
ggplot(df, aes(x = name, y = val, fill = name)) +
geom_bar(stat = "identity") +
geom_errorbar(aes(ymin = val - 10,
ymax = val + 10)) +
scale_y_continuous(expand = c(0,0)) +
coord_cartesian(ylim = c(0, max(df$val) + 10))

R ggplot placing labels on error bars

I can create a bar chart with error bars but how can I put labels on the higher (vLABELH) and lower error bars (vLABELL).
library(ggplot2)
vx <- c(1:5)
vBAR <- c(0.1,0.2,0.3,0.4,0.5)
vLINE1 <- c(0.15,0.25,0.35,0.45,0.55)
vLINE2 <- c(0.15,0.25,0.35,0.45,0.55)
vLINE3 <- c(0.05,0.15,0.25,0.35,0.45)
vLABELL<- c(0.05,0.15,0.25,0.35,0.45)
vLABELH <- c(0.15,0.25,0.35,0.45,0.55)
df1 <- as.data.frame(cbind(vx,vBAR,vLINE1,vLINE2,vLINE3,vLABELL,vLABELH))
class(df1)
barchart1 <- ggplot(df1, aes(x=as.factor(vx),y=vBAR)) + geom_bar(fill="blue", colour="blue")+
geom_errorbar(aes(ymin=vLINE3, ymax=vLINE1 ))
barchart1
I suppose you're looking for geom_text.
ggplot(df1, aes(x = as.factor(vx), y = vBAR)) +
geom_bar(stat = "identity", fill = "blue", colour = "blue") +
geom_errorbar(aes(ymin = vLINE3, ymax = vLINE1 )) +
geom_text(aes(label = vLABELH, y = vLINE1), vjust = -.5) +
geom_text(aes(label = vLABELL, y = vLINE3), vjust = 1.5)

Resources