user3205756
user3205756

Reputation: 43

Number format in ggplot: no sign on y-axis-labels

The answers to this question were extremely helpful for me, too. There is just one thing I still need a hint to:

How do I get rid of the sign in the y-scale-Labels if I iterate the plot over a set of districts with varying y-values?

This is my code so far:

for (district in DISTRICTS) {
HW.dist <- subset(HW,DISTRICT==district)
  py <- ggplot(data=HW.dist,aes(x=as.numeric(AGE),fill=SEX))
  py <- py +
    geom_bar(subset=.(SEX=="F"), binwidth=1) +
    geom_bar(subset=.(SEX=="M"), binwidth=1,aes(y=..count..*(-1))) +
    scale_fill_grey(guide = guide_legend(title = NULL)) +
    scale_x_discrete(breaks=seq(0,120,by=5),labels=abs(seq(0,120,by=5))) +
    labs(y = "Count", x = "Age") +
    labs(title = "Random title text") +
    theme(plot.title = element_text(size = rel(1.5))) +
    coord_flip()
  print(py)
}

(DISTRICT obviously is just a list with the 16 districts.)

Sample data (HW):

SEX  AGE            DISTRICT 
 M   048          Innenstadt
 M   022          Innenstadt
 M   029            Neustift
 M   053            Neustift
 F   044             Heining
 F   017             Heining
 F   056            Neustift
 M   054            Neustift
 M   030            Altstadt
 M   029           Schalding
 F   029            Altstadt

RESULTS:

Including the help I got here and some fiddling with the y-axis-breaks, this is the relevant part of the final code (with some comments):

# How broad will the pyramid be?
f <- max(table(as.numeric(HW$AGE),HW$SEX)) 
# Round that up to the next power of 10 (eg 557 -> 600)
f <- ceiling(f/10^floor(log10(f)))*10^floor(log10(f)) 
# Use that power of 10 as breaks
l <- 10^floor(log10(f))
# f and l will be used in the 'scale_y_discrete' statement below

py <- ggplot(data=HW,aes(x=as.numeric(AGE),fill=MW))  
py +
  geom_bar(subset=.(SEX=="F"), binwidth=1) +
  geom_bar(subset=.(SEX=="M"), binwidth=1 ,aes(y=..count..*(-1))) +
  scale_fill_grey(guide = guide_legend(title = NULL)) +
  scale_x_continuous(breaks=seq(0,120,by=10),labels=abs(seq(0,120,by=10))) +
  scale_y_discrete(breaks=seq(-f,f,by=l),labels=abs) +
  labs(y = "Count", x = "Age") +
  labs(title = "Random title text") + theme(plot.title = element_text(size = rel(2))) +
  # Tell ggplot not to allocate drawing space for the negative (=male) on top (flipped: right) of the positive (=female) part of the graph
  coord_flip(xlim = c(0,110), ylim = c(-f, f))

This works perfect for me, even within a Loop through the districts.

Thanks a lot!

Upvotes: 4

Views: 3837

Answers (1)

Ram Narasimhan
Ram Narasimhan

Reputation: 22516

Since you are doing a coord_flip you have to change the labels of your y-axis values (which becomes the x-axis when flipped).

Add the following line, but instead of (-5 to +5) set them to be whatever is the maximum +ve and -ve values that your geom_bars can be, depending on the data. We are just making the axis value labels to be the abs values of the breaks.

+ scale_y_discrete(breaks=seq(-5,5,by=1),labels=abs(seq(-5,5,by=1)))     

I don't have your full data, but adding the line above took care of the minus sign and produced: enter image description here

Update based on OP's clarification

Looks like Hadley has already thought of this. Without specifying the breaks, just make the values to be absolute numbers so that it doesn't print negative values. Try adding:

+ scale_y_discrete(labels=abs)

Upvotes: 4

Related Questions