1

I already browsed a lot, but unfortunately I just find vague information. I want to display a sex ratio over length classes. To achieve that I did a stacked barplot with ggplot2 (geom_bar). This is the code:

Data <- data.frame(LCnew=c(30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40), 
                   sex=c(1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2))
ggplot(Data, aes(x=factor(LCnew), fill=factor(sex)))+geom_bar(position="fill") +  scale_x_discrete("Lengthclass [mm]") +  scale_y_continuous("Proportion of sexes") + scale_fill_manual(values=cols)

cols is just a simple vector with colours in it.

This is the plot so far:

enter image description here

My problem is that I am not able to change the axis text. I just want text below every fifth bar, otherwise they are overlapping. I tried it with the limits and breaks command, but this just gave me an empty graph.

scale_x_continuous("Standard Length [mm]",limits=c(30,85),breaks=c(30,35,40,45,50,55,60,65,70,75,80,85))

Any suggestions?

Jaap
  • 81,064
  • 34
  • 182
  • 193
kilewi
  • 11
  • 1
  • 1
  • 3
  • 1
    add some data to the question – Mateusz1981 Oct 21 '15 at 14:01
  • to be honest: I don't know how to add data...it's my first question here and I'm still struggeling. sorry for that :/ – kilewi Oct 21 '15 at 14:06
  • 1
    [Some info about how to give a minimal reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example/5963610). – Jaap Oct 21 '15 at 14:09
  • Sorry for being a bit overchallenged. My dataset has the same structure like this matrix: 'y <- matrix(c(30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2),nrow=22, ncol=2) colnames(y) <- c("length","sex")' but when I want to plot it, it get an error message that ggplot does not know how to deal with data of class matrix. but at least it has the same structure like my data.... – kilewi Oct 21 '15 at 14:32

2 Answers2

4

If you want to prevent that the labels are overlapping, there are several strategies you can follow:

1) Define the breaks:

ggplot(y, aes(x=factor(length), fill=factor(sex))) +
  geom_bar(position="fill", width=0.7) +
  scale_x_discrete("Standard Length [mm]", breaks=c(300000,350000,400000)) +
  scale_y_continuous("Proportion of sexes", expand=c(0,0)) + 
  scale_fill_manual("Sex", values=c("blue","pink"), labels=c("Male","Female")) +
  theme_minimal()

which gives the following plot:

enter image description here

2) Change the angle of the labels:

ggplot(y, aes(x=factor(length), fill=factor(sex))) +
  geom_bar(position="fill", width=0.7) +
  scale_x_discrete("Lengthclass [mm]", expand=c(0,0)) +
  scale_y_continuous("Proportion of sexes", expand=c(0,0)) + 
  scale_fill_manual("Sex", values=c("blue","pink"), labels=c("Male","Female")) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle=90, vjust = 0.5))

which gives:

enter image description here

3) Rotate the plot:

ggplot(y, aes(x=factor(length), fill=factor(sex))) +
  geom_bar(position="fill", width=0.7) +
  scale_x_discrete("Lengthclass [mm]", expand=c(0,0)) +
  scale_y_continuous("Proportion of sexes", expand=c(0,0)) + 
  scale_fill_manual("Sex", values=c("blue","pink"), labels=c("Male","Female")) +
  coord_flip() +
  theme_minimal()

which gives:

enter image description here


Used data:

y <- structure(list(length = c(300000, 300000, 310000, 310000, 320000, 320000, 330000, 330000, 340000, 340000, 350000, 350000, 360000, 360000, 370000, 370000, 380000, 380000, 390000, 390000, 400000, 400000, 300000, 310000, 330000, 340000, 360000, 380000, 390000), 
                    sex = c(1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 2)), .Names = c("length", "sex"), row.names = c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "110", "41", "71", "101", "131", "171", "201"), class = "data.frame")
Jaap
  • 81,064
  • 34
  • 182
  • 193
  • thank you so much Jaap! now i just have to decide which option i like most ;) you helped me a lot!! – kilewi Oct 21 '15 at 17:02
  • @kilewi In that case it is considered good practice to accept the answer. You can do that by clicking the green checkmark under the voting buttons. See also this help page: [What should I do when someone answers my question?](http://stackoverflow.com/help/someone-answers) – Jaap Oct 21 '15 at 17:57
1

Try adding 'labels'

scale_x_continuous("Standard Length [mm]", breaks=c(30,35,40,45,50,55,60,65,70,75,80,85),labels=c(30,35,40,45,50,55,60,65,70,75,80,85))
heathobrien
  • 1,027
  • 7
  • 11
  • thank you! i think i did not describe my problem sufficient. my dataset has more than 40 lengthclasse (x values) and when each number is shown, it is just too crowded. that's why i wanted to just show the every fifth number (30,35,40,45,50....75,80). but the answer of jaap and lawyeR already solved that. still thanks a lot for your effort!! – kilewi Oct 21 '15 at 16:57