Barplot

53 views
Skip to first unread message

julienhi...@gmail.com

unread,
May 19, 2015, 3:34:02 PM5/19/15
to ggp...@googlegroups.com
Hi everyboy,

I'm currently dealing with some issues with ggplot.

I want to build a barplot showing a weekly species composition (see figure attached).

But I don't want a count on the y axe, i would prefer a proportion for each species with a total of 100%. 

More, I would have my bar plot centered in weeks 47 to 9 (and not 1 to 50 like it is currently). 

How can I do that ?

Thank you for answering

Julien
Compo hebdo.jpeg

Dennis Murphy

unread,
May 19, 2015, 4:37:30 PM5/19/15
to julienhi...@gmail.com, ggplot2
Hi:

Please Google "R reproducible example" and read at least the first two
hits (from StackOverflow and Hadley Wickham). Then reformulate your
question with sufficient data and code to reproduce your problem.

If each bar is supposed to total 100%, then you could use position =
"fill" in geom_bar(). As for your other question, I'm not sure what
you're after. One way you could separate the two groups of plots is to
define a variable that divides the data into two groups (e.g. gp <-
Semaine <= 25) and then facet by that variable, using scales =
"free_x" to get separate x-scales, but I don't know if that's what you
want...

Dennis
> --
> --
> You received this message because you are subscribed to the ggplot2 mailing
> list.
> Please provide a reproducible example:
> https://github.com/hadley/devtools/wiki/Reproducibility
>
> To post: email ggp...@googlegroups.com
> To unsubscribe: email ggplot2+u...@googlegroups.com
> More options: http://groups.google.com/group/ggplot2
>
> ---
> You received this message because you are subscribed to the Google Groups
> "ggplot2" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to ggplot2+u...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

julienhi...@gmail.com

unread,
May 19, 2015, 5:53:57 PM5/19/15
to ggp...@googlegroups.com, julienhi...@gmail.com
Here is my code :

require(ggplot2)

####Loading database####
data2 <- structure(list(Semaine = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 
47L, 48L, 49L, 50L, 51L, 52L, 53L), Obs = c(61L, 25L, 0L, 2L, 
7L, 3L, 8L, 5L, 2L, 0L, 11L, 8L, 4L, 8L, 153L, 0L), Mega = c(17L, 
7L, 0L, 3L, 9L, 3L, 4L, 1L, 1L, 0L, 4L, 28L, 12L, 11L, 3L, 1L
), Marmo = c(401L, 199L, 10L, 50L, 147L, 52L, 34L, 89L, 49L, 
4L, 114L, 555L, 369L, 325L, 270L, 14L)), .Names = c("Semaine", 
"Obs", "Mega", "Marmo"), class = "data.frame", row.names = c(NA, 
-16L))

####Graph####
x11()
qplot(Semaine, data=data2, geom="bar", fill=Espece)


#My first issue is exactly what you understood, i want all of these bars to total 100%
#My second one is purely visual, i want my bars on the middle of the graph (centered from week 47 to 9) and not at both sides.

Hope it works
Thx for help

Ron Crump

unread,
May 20, 2015, 4:28:26 AM5/20/15
to ggp...@googlegroups.com
Julien,

> require(ggplot2)
>
> ####Loading database####
> data2 <- structure(list(Semaine = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L,
> 47L, 48L, 49L, 50L, 51L, 52L, 53L), Obs = c(61L, 25L, 0L, 2L,
> 7L, 3L, 8L, 5L, 2L, 0L, 11L, 8L, 4L, 8L, 153L, 0L), Mega = c(17L,
> 7L, 0L, 3L, 9L, 3L, 4L, 1L, 1L, 0L, 4L, 28L, 12L, 11L, 3L, 1L
> ), Marmo = c(401L, 199L, 10L, 50L, 147L, 52L, 34L, 89L, 49L,
> 4L, 114L, 555L, 369L, 325L, 270L, 14L)), .Names = c("Semaine",
> "Obs", "Mega", "Marmo"), class = "data.frame", row.names = c(NA,
> -16L))
>
> ####Graph####
> x11()
> qplot(Semaine, data=data2, geom="bar", fill=Espece)

Either your data or your qplot command are wrong. There is no Espece
in the data.frame provided so the fill will fail. The data appear
to represent counts with the columns being the species, so there should
be something in the qplot command to tell it not to bin the data within
Semaine, but the data are still in the wrong format even then.

I suspect you have sent a summary of your data, which will result in a
different answer to sending the actual data.

But here goes...

> #My first issue is exactly what you understood, i want all of these bars
> to total 100%

Given the data supplied I would convert the the three species columns
into percentages to begin with:

data1 <- data2

data2[,c("Obs","Mega","Marmo")] <-
data2[,c("Obs","Mega","Marmo")]*100/rowSums(data2[,c("Obs","Mega","Marmo")])

then change the data.frame to long format...

library(reshape2)
mdata<-melt(data2,id.vars="Semaine",variable.name="Espece")

and then (sorry I don't use qplot, so I'm sticking with ggplot here)..

ggplot(mdata,aes(x=Semaine,y=value,fill=Espece))+geom_bar(stat="identity")

Alternatively, without converting the data into percentages:

mdata<-melt(data1,id.vars="Semaine",variable.name="Espece")
ggplot(mdata,aes(x=Semaine,y=value,fill=Espece))+geom_bar(stat="identity",position="Fill")

But that gives a 0-1 rather than 0-100 scale (could probably be
modified by relabelling a scale?).

> #My second one is purely visual, i want my bars on the middle of the
> graph (centered from week 47 to 9) and not at both sides.

I assume therefore that the data are weeks of the year and
that the 1-9 are from the year after the 47-53? You could
make week a factor:

mdata1$week <- factor(mdata1$Semaine,levels=c(47:53,1:9))
ggplot(mdata1,aes(x=week,y=value,fill=Espece))+geom_bar(stat="identity",position="Fill")

If your actual data aren't in the form of the data2 counts sent, I
suspect they are more like:

ddd<-do.call(rbind,apply(data1,1,function(x){data.frame(Semaine=rep(x[1],sum(x[2:4])),Espece=rep(c("Obs","Mega","Marmo"),times=x[2:4]))}))

In which case your original qplot command works (substituting ddd for
data2) as does this:

ddd$week <- factor(ddd$Semaine,levels=c(47:53,1:9))
ggplot(ddd,aes(x=week))+geom_bar(aes(fill=Espece),position="Fill")+ylab("Proportion")+xlab("Week")

> Hope it works

No it didn't, and you really should have checked that before sending it.
I'm only having a play with this as I have some other stuff running,
otherwise I would have stopped as soon as the example failed.

I'm not as grumpy as that last paragraph sounded.

Ron.

Dennis Murphy

unread,
May 20, 2015, 1:01:22 PM5/20/15
to julienhi...@gmail.com, ggplot2
I had the same experience as the other poster, and I resorted to
roughly the same solution path, but with somewhat different code.

# Reformat the data from wide to long form, assuming that Obs,
# Mega and Marmo are the three species in question
library(reshape2)
dm <- melt(data2, id = "Semaine", variable.name = "Espece")

# Create a factor to split the two time periods
dm$gp <- cut(dm$Semaine, c(0, 25, 100), labels = c("Period 1", "Period 2"))

# Use position = "fill" to stack by relative frequency and faceting
# to plot the two time periods in different panels
ggplot(dm, aes(x = Semaine, y = value, fill = Espece)) +
geom_bar(stat = "identity", position = "fill") +
facet_wrap(~ gp, scale = "free_x") +
labs("Relative frequency")

Is this closer to what you had in mind?

Dennis

julienhi...@gmail.com

unread,
May 20, 2015, 3:14:10 PM5/20/15
to ggp...@googlegroups.com, r.e....@warwick.ac.uk
Ron,

I'm sorry, I don't know what happened but yes it is not the right data set ... My bad. And you're right, i should have checked that ...

Anyway, your stuff works perfectly.

Thank you for time spent

Julien

julienhi...@gmail.com

unread,
May 20, 2015, 3:17:20 PM5/20/15
to ggp...@googlegroups.com, julienhi...@gmail.com
Denis,

Ron's solution is much closer from what I would
Anyway, thank you too !

Julien
Reply all
Reply to author
Forward
0 new messages