2

I'm new to ggplot2, and I have a bar plot of mean responses that I Frankensteined out of sample code.

dput() output to reproduce graph:

> dput(mainerrors.df)
structure(list(sex = structure(c(1L, 1L, 1L, 2L, 2L, 2L), .Label = c("Male", 
"Female"), class = "factor"), condition = structure(c(1L, 2L, 
3L, 1L, 2L, 3L), .Label = c("Weather", "Negative", "Positive"
), class = "factor"), N = c(19, 18, 26, 55, 50, 49), willingness = c(5.47368421052632, 
5.48148148148148, 5.97435897435897, 6.37575757575758, 5.88666666666667, 
6.2312925170068), sd = c(1.3067525929499, 1.41524021482219, 1.05797742854762, 
0.865560893471263, 1.13611104180873, 0.969927645336604), se = c(0.299789605098861, 
0.333575317636226, 0.207486444350194, 0.116712207066377, 0.160670364368774, 
0.138561092190943), ci = c(0.629834588787353, 0.703782401529606, 
0.427326331312926, 0.233993886626096, 0.32287918557602, 0.278595748013486
)), .Names = c("sex", "condition", "N", "willingness", "sd", 
"se", "ci"), row.names = c(NA, 6L), class = "data.frame")

Code to reproduce graph:

figure.4 <- ggplot(mainerrors.df, aes(x = condition, y = willingness)) +
                facet_wrap(~sex) +
                geom_bar(stat="identity", colour="black", aes(fill=sex)) +
                geom_errorbar(aes(ymin=willingness-ci, ymax=willingness+ci),
                              size=.3,
                              width=.2,
                              position=position_dodge(.9)) +
                scale_fill_brewer(palette="Set3", name="Sex",
                                  breaks=c("Male", "Female"),
                                  labels=c("Male", "Female")) +
                scale_x_discrete("Peer Comment Frame") +
                scale_y_continuous("Willingness to use a condom (95% CI)", breaks=1:7)
                theme(plot.background = element_rect(fill = "transparent", colour = NA),
                      legend.position = "none",
                      axis.text.x = element_text(size=16),
                      axis.text.y = element_text(size=16),
                      axis.title.x = element_text(face="bold", colour="#7f7f7f", size=16, vjust=0.1),
                      axis.title.y = element_text(face="bold", colour="#7f7f7f", size=16),
                      strip.text.x = element_text(size = 16, colour = "black"))

Everything looks very nice, except I can't get the axis titles the way I want them no matter how much I play with vjust. So I thought: why not put the axis titles in the plot itself, instead of hanging way out there? The facet titles are a perfect example of how I would like my graph to look (it seems I can't post images directly): http://postimg.org/image/cnma6zp99/

I would like the x-axis/y-axis titles to run along the bottom/left side of the plot like Male/Female does at the top, because it would look much more coherent and avoid all the positioning issues. Is there any way to do this (or a way to control axis title positioning more precisely than vjust allows, but this would be optimal)?

EDIT: I photoshopped together a rough example of how I'm envisioning my graph: enter image description here

agstudy
  • 119,832
  • 17
  • 199
  • 261
  • 1
    Hi there! Please make your post reproducible. Read the post [**how to make a great reproducible example**](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) on how to do this. Thank you. – Arun Mar 26 '13 at 12:20
  • Sorry about that! I will get on it ASAP. Thanks for the tip. – Christian Hummeluhr Mar 26 '13 at 13:35
  • 1
    There is probably no way to achieve what you ask without quite some effort in customized grid graphics code. Possible, but probably not worth the effort. – joran Mar 26 '13 at 14:05
  • Thanks for saving me the time. I guess I'll go find out how to make a suggestion to ggplot2! – Christian Hummeluhr Mar 26 '13 at 14:33

1 Answers1

1

It is not clear waht do you want to do , but here a start of a solution inspired from @baptiste. solution here. The main idea is to define a custom element to hold the customization of x and y titles. The solution is far from being finished but it shows the idea. You can also use lattice. This kind of customization is simple withe the lattice package.

enter image description here

require(ggplot2)
require(grid)

# user-level interface to the element grob
my_axis = function(text,rot=0) {
  structure(
    list(text=text,rot=rot),
    class = c("element_custom","element_blank", "element") # inheritance test workaround
  )
}
# returns a gTree with two children: the text label, and a rasterGrob below
element_grob.element_custom <- function(element,...)  {
  g2 <- rectGrob(gp=gpar(fill='red',alpha=0.5))
  g1 <- textGrob(element$text, x=0.5,vjust=0.5,rot  =element$rot)
  gTree(children=gList(g2,g1), cl = "custom_axis")
}
# gTrees don't know their size and ggplot would squash it, so give it room
 grobHeight.custom_axis = heightDetails.custom_axis = function(x, ...)
   unit(1, "lines")


ggplot(mtcars,aes(mpg,disp))+geom_point()+facet_grid(.~vs)+
  theme_bw() +
  theme(axis.title.x = my_axis('my custom x title'),
        axis.title.y = my_axis('my custom y title',rot=90))
Community
  • 1
  • 1
agstudy
  • 119,832
  • 17
  • 199
  • 261
  • That looks almost exactly what I was looking for, provided I can manage to position the red bars within the plot itself somehow! Thanks for the help, I'll play around with this for a bit and see what turns up. I'd upvote you, but apparently I can't because I have no rep? Harsh. – Christian Hummeluhr Mar 26 '13 at 15:48
  • I mean the red rectangles with the axis titles, sorry. – Christian Hummeluhr Mar 28 '13 at 09:37
  • I've added an example I photoshopped together to show what I mean more clearly. Currently I'm just trying to figure out how to prevent ggplot from squeezing the y-axis rectangle. – Christian Hummeluhr Mar 28 '13 at 10:23