2

This is a minimal example that shows the plots I am trying to make.

Data looks like this:

plot1 = data.frame(
    Factor1 = as.factor(rep('A', 4)),
    Factor2 = as.factor(rep(c('C', 'D'), 2)),
    Factor3 = as.factor(c( rep('E', 2), rep('F', 2))),
    Y = c(0.225490, 0.121958, 0.218182, 0.269789)
)

plot2 = data.frame(
    Factor1 = as.factor(rep('B', 4)),
    Factor2 = as.factor(rep(c('C', 'D'), 2)),
    Factor3 = as.factor(c( rep('E', 2), rep('F', 2))),
    Y = c(-0.058585, -0.031686, 0.013141, 0.016249)
)

While the basic code for plotting looks like this:

require(ggplot2)
require(grid)

p1 <- ggplot(data=plot1, aes(x=Factor2, y=Y, fill=factor(Factor3))) +
    ggtitle('Type: A') +
    coord_cartesian(ylim = c(-0.10, 0.30)) +
    geom_bar(position=position_dodge(.9), width=0.5, stat='identity') +
    scale_x_discrete(name='Regime',
        labels=c('C', 'D')) +
    scale_y_continuous('Activations') +
    scale_fill_brewer(palette='Dark2', name='Background:',
        breaks=c('E','F'),
        labels=c('E','F')) +
    theme(axis.text=element_text(size=11),
        axis.title.x=element_text(size=13, vjust=-0.75),
        axis.title.y=element_text(size=13, vjust=0.75),
        legend.text=element_blank(),
        legend.title=element_blank(),
        legend.position='none',
        plot.title=element_text(hjust=0.5))

p2 <- ggplot(data=plot2, aes(x=Factor2, y=Y, fill=factor(Factor3))) +
    ggtitle('Type: B') +
    coord_cartesian(ylim = c(-0.10, 0.30)) +
    geom_bar(position=position_dodge(.9), width=0.5, stat='identity') +
    scale_x_discrete(name='Regime',
        labels=c('C', 'D')) +
    scale_y_continuous('Activations') +
    scale_fill_brewer(palette='Dark2', name='Background:',
        breaks=c('E','F'),
        labels=c('E','F')) +
    theme(axis.text=element_text(size=11),
        axis.title.x=element_text(size=13, vjust=-0.75),
        axis.title.y=element_blank(),
        legend.text=element_text(size=11),
        legend.title=element_text(size=13),
        plot.title=element_text(hjust=0.5))

pushViewport(viewport(
    layout=grid.layout(1, 2, heights=unit(4, 'null'),
        widths=unit(c(1,1.17), 'null'))))
print(p1, vp=viewport(layout.pos.row=1, layout.pos.col=1))
print(p2, vp=viewport(layout.pos.row=1, layout.pos.col=2))

And the figure looks like this:

Attempt

However, I would need something like this:

Correct

Thick black lines are the reference values. They are constant and the Figure presents that "reference situation". However, in other plots that I need to produce bars will change but the reference values should remain the same to make the comparisons straightforward and easy. I know I should be using geom_segment() but those lines in my attempts to make this work are just missing the bars.

Any help/advice? Thanks!

1
  • 1
    Maybe just use a geom_point for the reference; segment seems hard bc you x-axis isnt numeric. Or you could do a geom_col of the references before plotting this on top and use alpha to make it mostly see through Commented Dec 14, 2019 at 14:54

2 Answers 2

4

I was able to do this using geom_errorbarh. For instance, with the second figure:

p1 + 
  geom_errorbarh(
    aes(xmin = as.numeric(Factor2)-.2,xmax = as.numeric(Factor2)+.2), #+/-.2 for width
    position = position_dodge(0.9), size = 2, height = 0
  )

OUTPUT: enter image description here And, if I understand the other plots you describe, you can specify the reference data in those, eg data = plot1

Sign up to request clarification or add additional context in comments.

Comments

2

If your references are not going to be changed, you can create a second dataset and merge it to the dataset you are going to plot.

Here, I first add plot1 and plot2. Then, I create a new dataset that will be the reference dataset.

library(dplyr)
new_df = rbind(plot1, plot2)
ref_plot = new_df
ref_plot <- ref_plot %>% rename(Ref_value = Y)

Then, now you have the new_df which is the dataset to be plot and ref_plot that contains references values for each conditions.

Instead of using grid and create two different plot that I will merge after, I preferred to use facet_wrap which put all plots on the same figure. It is much more convenient and don't require to write twice the same thing.

As mentioned by @AHart few minutes before me, you can use geom_errorbar to define your reference values on the plot. The difference is I prefere to use geom_errorbar instead of geom_errobarh.

Here is for the plot:

library(ggplot2)
new_df %>% left_join(ref_plot) %>% 
  ggplot(aes(x = Factor2, y = Y, fill = Factor3))+
  geom_bar(stat = "identity", position = position_dodge())+
  geom_errorbar(aes(ymin = Ref_value-0.00001, ymax = Ref_value+0.0001, group = Factor3), position = position_dodge(.9),width = 0.2)+
  facet_wrap(.~Factor1, labeller = labeller(Factor1 = c(A = "Type A", B = "Type B"))) +
  scale_x_discrete(name='Regime',
                   labels=c('C', 'D')) +
  scale_fill_brewer(palette='Dark2', name='Background:',
                    breaks=c('E','F'),
                    labels=c('E','F')) +
  theme(axis.text=element_text(size=11),
        axis.title.x=element_text(size=13, vjust=-0.75),
        axis.title.y=element_blank(),
        legend.text=element_text(size=11),
        legend.title=element_text(size=13),
        plot.title=element_text(hjust=0.5))

enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.