How to Make Dodge in Geom_Bar Agree with Dodge in Geom_Errorbar, Geom_Point

How can I get geom_errorbar to dodge correctly on a bar chart in ggplot2?

If you move fill into the global aes() then position_dodge() will work as expected. Alternatively you could add the grouping variable via group to geom_errorbar().

ggplot(d, aes(x = bin, y = beta, 
ymin = beta - 1.96*se, ymax = beta+1.96*se, fill = type)) +
geom_bar(position = position_dodge(), stat="identity") +
geom_errorbar(position=position_dodge(.9), width = .2)

The issue with position_dodge2() appears to be what is discussed in this GitHub issue, which can be solved via the padding argument. Notice there is no longer a width argument in geom_errorbar() with this approach.

ggplot(d, aes(x = bin, y = beta, 
ymin = beta - 1.96*se, ymax = beta+1.96*se, fill = type)) +
geom_bar(position = position_dodge2(), stat="identity") +
geom_errorbar(position = position_dodge2(.9, padding = .6))

mapping error bars to geom_points with position_dodge

You should bring the aesthetics into the ggplot part and leave them out of the aes for the geom. Then the errorbars will be plotted where the points are plotted.
Using too many aesthetics will matching the different geoms again tricky.

Maybe you can use a facet instead.

library(ggplot2)

ggplot(df1, aes(x=factor(F), y = median/1000,shape=mr, color =mr)) +
geom_point(position=position_dodge(width=.5)) +
geom_errorbar(
aes(ymin = lci/1000, ymax = uci/1000),
width = 0.5,
position=position_dodge(width=.5)) +
theme_classic()

Sample Image

ggplot(df1, aes(x=factor(F), y = median/1000,shape=mr, color =mr)) +
geom_point(position=position_dodge(width=.5)) +
geom_errorbar(
aes(ymin = lci/1000, ymax = uci/1000),
width = 0.5,
position=position_dodge(width=.5)) +
facet_wrap(~start)+
theme_classic()

Sample Image

How to make geom_linerange dodge position according to geom_point

You can use position_dodge2() to get the correct "dodging".

From the documentation:

position_dodge() requires the grouping variable to be be specified in the global or geom_* layer. Unlike position_dodge(), position_dodge2() works without a grouping variable in a layer.

Therefore you if you want to use position_dodge, put fill = group2 in ggplot(aes()) or directly use position_dodge2 in geom_linerange.

library(ggplot2)

ggplot(tot.risk, aes(x = x, y = predicted)) +
scale_fill_manual(values=c("white", "black"))+
geom_point(pch=21, size=6, aes(fill=group2), position = position_dodge(width = 0.8))+
scale_y_continuous(limits = c(0,0.8))+
geom_linerange(aes(ymin=conf.low, ymax=conf.high), position = position_dodge2(width = 0.8))+
theme_classic()+
theme(axis.ticks.y = element_blank(),
axis.text.y = element_blank(),
axis.text.x = element_text(size=12),
axis.title.x = element_text(size=14),
axis.title.y = element_text(size=14),
legend.text = element_text(size=14),
legend.title = element_blank())+
xlab("Type of risk")+
ylab("Probability of selection")

position_dodge2

Creating ggplot geom_point() with position dodge 's-shape'

This could be achieved by

  1. grouping the data by x-axis categories
  2. arranging by the y-axis value

which ensures that the points are plotted in ascending order of the values for each category.

somatic.variants <- read.delim("https://gist.githubusercontent.com/wudustan/57deecdaefa035c1ecabf930afde295a/raw/1594d51a1e3b52f674ff746caace3231fd31910a/Lawrence.S2.txt", stringsAsFactors=T)
cancer_rates <- tapply(somatic.variants$logn_coding_mutations, somatic.variants$tumor_type, median)
cancer_rates <- cancer_rates[order(cancer_rates, decreasing=F)]
somatic.variants$tumor_type <- factor(somatic.variants$tumor_type, levels = names(cancer_rates))

library(ggplot2)
library(GGally)
library(dplyr)

somatic.variants <- somatic.variants %>%
group_by(tumor_type) %>%
arrange(n_coding_mutations)

ggplot(data = somatic.variants,
mapping = aes(x = tumor_type,
y = log10(n_coding_mutations))) +
geom_point(position = position_dodge2(.9), size = .25) +
scale_x_discrete(position = "top") +
scale_y_continuous(labels = c(0,10,100,1000,10000), expand = c(0,0)) +
geom_stripped_cols() +
theme_bw() +
theme(axis.title.x = element_blank(),
axis.text.x = element_text(angle = 315, hjust = 1, size = 12),
panel.grid = element_blank()) +
labs(y = "Coding mutations count") +
stat_summary(fun = median,
geom="crossbar",
size = 0.25,
width = 0.9,
group = 1,
show.legend = FALSE,
color = "#FF0000")
#> Warning: Removed 29 rows containing non-finite values (stat_summary).

Sample Image

Dodge geom_errorbar by group when there are missing values

This is probably not the most elegant solution but you could use geom_pointrange instead and make the upr and lwr values the same as your value column so they get plotted without error bars.

e.g.

    a$lwr <- ifelse(is.na(a$lwr), a$value, a$lwr)
a$upr <- ifelse(is.na(a$upr), a$value, a$upr)

ggplot(a) +
geom_pointrange(aes(x=taxon, y=value, ymin=lwr, ymax=upr, shape=type, col=period),
position = position_dodge(width = 0.5)) +
theme_bw()

This gives this graph, which sounds like what you want:
Pointrange Example



Related Topics



Leave a reply



Submit