-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfoodwebplot.R
150 lines (124 loc) · 5.28 KB
/
foodwebplot.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
###############Food web plotting function################
### Date: 12/13/2011
### Author: Edmund Hart ([email protected])
### Description: A function to create grahps of trophic networks using ggplot2
### Plots food webs in a circular graph
### requires ggplot2
#########################################################
library(ggplot2)
########## support function create.xy
########## returns regularly spaced circular coordinates for the size
########## of your web
create.xy <- function(po){
degs <- seq(0,2*pi,by=(2*pi/(po)))
return(cbind(cos(degs),sin(degs)))
}
############Plotting function##############
# plot.webgg() requires two arguments:
# ARGUMENTS: web - first is a square S x S matrix of 0's and 1's where S is the total
# number of species in the web
# columns are consumers and rows are species that are consumed
# therefore a 1 in row 5 and column 8 means that species 8 eats species 5
# Use the function t() if your matrices are oppositely arranged
#labels - is a vector of length S containing string values for the color of each consumer
# species link.
#
# RETURNED VALUES: The function creates a list with two values. The first is
# a ggplot2 object accessed as object$plot
# The next is a dataframe of raw x-y coordinates to connect accessed as object$rawdat
plot.webgg <- function(web,labels){
xy <- create.xy(dim(web)[1])
xy <-data.frame(xy)
cons <- vector()
my.plot<- ggplot(xy,aes(x=X1,y=X2))+geom_point()+xlab("")+ylab("")
###Suppress warnings
options(warn=-1)
####Create output frame
p.df <- data.frame(matrix(NA,ncol=4,nrow=0))
###Create label index
label.in <- vector()
for(i in 1:dim(web)[1]){
#select the consumer links
cons <- which(web[,i]==1)
#####Now I need to have an if statement if there are no links
if(length(cons)>0){
#Now create repeat the one set of points that is being drawn
#ordering with odd numbers
tmp1 <-data.frame(cbind(rep(xy[i,1],length(cons)),rep(xy[i,2],length(cons)),seq(1,2*length(cons),by=2)))
#Next select the nodes to connect to
tmp2 <- data.frame(cbind(xy[cons,]))
#add an index of sequenced even numbers
tmp2$X3 <- seq(2,2*length(cons),by=2)
tmp <- rbind(tmp1,tmp2)
#now sort them to get the order correct
tmp <- tmp[order(tmp$X3),]
#Finally add a grouping variable
tmp$color <- rep(paste(labels[i],i),dim(tmp)[1])
p.df <- rbind(p.df,tmp)
# A tricky thing can be that your colors will be all wrong if
# If I don't adjust the label vector, shortening if for columns
# that are all 0's so instead I build up a label index
label.in <- c(label.in,i)
}
}
my.plot<-my.plot+geom_path(data=p.df,aes(x=X1,y=X2,group=color,colour=color))+scale_colour_manual(values=labels[label.in],legend=F)
my.plot <- my.plot+opts(axis.ticks = theme_blank(), axis.title.y = theme_blank(), axis.text.y = theme_blank(), axis.title.x = theme_blank(), axis.text.x = theme_blank())
return(list(plot=my.plot,rawdat=p.df))
}
##############Sample Data Generation######
# Data inputs: In this formulation the species that is consumed are the rows
# and the consumers are the columns
# Data example: Here I use a random network example
######Large random matrix
rand.mat <- matrix(rbinom(1600,1,.2),ncol=40,nrow=40)
diag(rand.mat)<- 0
lab <- rep("Black",40)
test<- plot.webgg(rand.mat,lab)
test$plot
####Small random matrix with colored links
rand.mat <- matrix(rbinom(100,1,.3),ncol=10,nrow=10)
diag(rand.mat)<- 0
lab <- c(rep("blue",3),rep("red",7))
test<- plot.webgg(rand.mat,lab)
test$plot
##############Note that overlapping colors
# can cause other colors (in this example it would be purple)
# this will normally not happen unless you have reciprocal links
# if anyone really wants that fixed I could figure it out
# lastly here is an example using a real food web from
# Bascompte et al. 10.1073/pnas.0501562102 at http://www.pnas.org/cgi/content/full/0501562102/DC1
# found at http://knb.ecoinformatics.org/knb/metacat?action=read&qformat=nceas&docid=bowdish.272
#
basc.web <- as.matrix(read.csv("basc_web.csv",header=F))
####Note that I cleaned it up by removing the row and column
#labels in the original files and saved it as a CSV
#now replace values greater than 0 but less than 1 with 1's
for(i in 1:249){basc.web[which(basc.web[,i]>0),i]<-1 }
labs <- rep("Black",249)
basc.plot <- plot.webgg(basc.web,labs)
basc.plot$plot
##########Finally an example generated with a niche-foodweb simulation
# from Williamns and Martinez: http://www.nature.com/nature/journal/v404/n6774/abs/404180a0.html
# I have a brief undocumented function below to generate the web, it
# requires S (# of species) and C (connectivity)
niche.model <- function(S,C){
new.mat <- matrix(0,nrow=S,ncol=S)
ci <- vector()
niche <- runif(S,0,1)
r <- rbeta(S,1,((1/(2*C))-1)) * niche
for(i in 1:S){ci[i]<-runif(1,r[i]/2,niche[i])}
#now set the smallest species niche value to have an n of 0
r[which(niche==min(niche))] <- .00000001
for(i in 1:S){
for(j in 1:S){
if(niche[j] > (ci[i]-(.5*r[i])) && niche[j]< (ci[i]+.5*r[i])){new.mat[j,i]<-1}
}
}
new.mat <- new.mat[,order(apply(new.mat,2,sum))]
return(new.mat)
}
###Plot
niche.web <- niche.model(20,.25)
labs <- rep("Black",20)
niche.plot <- plot.webgg(niche.web,labs)
niche.plot$plot