Christian Hummeluhr
Christian Hummeluhr

Reputation: 121

In-plot axis text in ggplot2

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

Upvotes: 2

Views: 1627

Answers (1)

agstudy
agstudy

Reputation: 121568

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))

Upvotes: 1

Related Questions