Skip to content

Commit

Permalink
new Figure 4 example
Browse files Browse the repository at this point in the history
  • Loading branch information
khufkens committed Aug 22, 2024
1 parent 4124066 commit 41e9c0a
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 27 deletions.
54 changes: 27 additions & 27 deletions Figure_1.r
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,15 @@ precip[is.na(gcc_loc)] = NA
fcover = read.table("./output/modelrun_01_fCover.txt")
# limit model output to the range of the Gcc data
# don't include spin-up
fcover[is.na(gcc_loc)] = NA
fcover[is.na(gcc_loc)] = NA

# scaling factor to be calculated from MAP and the
# optimized slope parameter
MAP = read.table("./output/MAP.txt")
scaling_factor = (1 * MAP[1,]) / (MAP[1,] + slope)

# padding to accomodate he inset scatter plot
offset = 2095
offset = 2095

leg = c('a','b','c','d','e','f')
phenocam_site_letter = c('g','c','j','m','f','d')
Expand All @@ -77,24 +77,24 @@ k=0

for (i in site_order){
k=k+1

# read data from original input file
input_data = read.table(sites_data[i],skip=12)

# get modis data if available
lat_long = scan(sites_data[i],what=character(),nmax=9)
lat = as.numeric(lat_long[6])
long = as.numeric(lat_long[9])

# construct dates string
input_dates = as.Date(paste(input_data[,1],input_data[,2],sep="-"),format="%Y-%j")

# calculate spinput length
spinup_length = input_dates[min(which(!is.na(gcc[,i]) == TRUE),na.rm=TRUE)]

# length of the time series
ts_length = length(input_dates)

# plot container
plot(input_dates,gcc[1:ts_length,i],
bty='n',
Expand All @@ -105,15 +105,15 @@ for (i in site_order){
ylim=c(0,1.3),
xlim=c(as.numeric(input_dates[ts_length-offset]),as.numeric(input_dates[ts_length]))
)

# format dates axis
locs <- tapply(X=input_dates, FUN=min, INDEX=format(input_dates, '%Y%m'))
at = input_dates %in% locs
at = at & format(input_dates, '%m') %in% c('01', '07')
at = at & format(input_dates, '%m') %in% c('01', '07')

# call a new plot
par(new=TRUE)

# plot the precipitation
plot(input_dates,precip[1:ts_length,i],
bty='n',
Expand All @@ -127,10 +127,10 @@ for (i in site_order){
ylim=c(0,150)
)
axis(4,cex.axis=1.2,tck=0.03,las=2,col='deepskyblue',col.axis='deepskyblue',at=c(0,70,140),lwd=1.5)

# call a new plot to plot GCC/fcover
par(new=TRUE)

# plot gcc
plot(input_dates,gcc[1:ts_length,i] * scaling_factor[1,i],
bty='n',
Expand All @@ -145,7 +145,7 @@ for (i in site_order){
cex.lab=1.5,
xlim=c(as.numeric(input_dates[ts_length-offset]),as.numeric(input_dates[ts_length]))
)

# add fcover
lines(input_dates,gcc[1:ts_length,i] * scaling_factor[1,i],
bty='n',
Expand All @@ -157,17 +157,17 @@ for (i in site_order){
lwd=2.3,
cex.lab=1.3,
xlim=c(as.numeric(input_dates[ts_length-offset]),as.numeric(input_dates[ts_length])))

# add fcover
lines(input_dates,fcover[1:ts_length,i],
ylim=c(0,1),
lty=1,
cex=0.2,
lwd=2.3,
col='red')

legend('topright',legend=leg[k],bty='n',cex=2.5)

# find location based upon name
loc = which(metadata$site == sites[i])

Expand All @@ -176,18 +176,18 @@ for (i in site_order){
bty='n',
cex=1.5,
bg='white')

# add nice axis
if(i == 6){
axis(side=1, at=seq(as.Date("2010/1/1"), as.Date("2015/1/1"), by = "year"),labels=F,tck=0.03,cex.axis=1.2,lwd=1.5)
axis(side=1, at=seq(as.Date("2010/6/30"), as.Date("2015/6/30"), by = "year"),labels=2010:2015,tck=F,cex.axis=1.2,lwd=1.5)
} else {
axis(side=1, at=seq(as.Date("2010/1/1"), as.Date("2015/1/1"), by = "year"),labels=F,tck=0.03,cex=1.5,lwd=1.5)
}
}

axis(2,at=c(0,0.5,1),cex.axis=1.2,tck=0.03,las=2,lwd=1.5)
axis(2,at=c(0,0.5,1),cex.axis=1.2,tck=0.03,las=2,lwd=1.5)
mtext("Precip. (mm)",4,3,cex=1,col='deepskyblue')

}

# legend
Expand All @@ -204,7 +204,7 @@ bottom= rev(bottom[2:7])

for (j in site_order){
df = na.omit(cbind(gcc[,j] * scaling_factor[1,j],fcover[,j]))

k = k + 1
par(fig=c(0.1,0.40,bottom[k],top[k]), new = TRUE)
plot(df,
Expand All @@ -218,21 +218,21 @@ for (j in site_order){
xlim=c(0,0.95),
ylim=c(0,0.95)
)

R = cor(df)[1,2]

rect(0,0,0.8,0.8,col = "white",border=0)
points(df,
pch=20,
col='grey50')

# labels
lines(c(0,0.8),c(0,0.8),lty=2)
legend(-0.15,0.9,legend=paste("R = ",round(R,2),sep=''),bty='n',cex=1.3)
axis(1,at=c(0,0.4,0.8),tck=0.03,labels=c(0,'',0.8),cex.axis=1.2,lwd=1.5)
axis(2,at=c(0,0.4,0.8),tck=0.03,labels=c(0,'',0.8),cex.axis=1.3,lwd=1.5)
mtext('Observed',1,2,cex=0.9)
mtext('Predicted',2,2,cex=0.9)

}
dev.off()
127 changes: 127 additions & 0 deletions Figure_4.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
require(zoo)
graphics.off()

error.bar <- function(x, y, upper, lower=upper, length=0.05,...){
if(length(x) != length(y) | length(y) !=length(lower) | length(lower) != length(upper))
stop("vectors must be same length")
arrows(x,y+upper, x, y, angle=90, code=3, length=length, ...)
}

# compile code
system('gfortran -ffree-form -ffree-line-length-200 -g func.f90 inc.f90 phenograss.f90 sann.f90 main.f90 -o phenograss', wait = T)

# run the code for the konza site, using site specific meteorological drivers
system('./a.out ./parameters/konza.txt r',wait = T)

# local weather
drivers = read.table("data/drivers/konza_grass.csv")
drivers_year = drivers[,1]
precip = drivers[,7]

# read konza yearly productivity measurements
df_bio = read.table('data/ancillary/konza_total_annual_biomass.csv',sep=',',header=T)
df_bio[is.na(df_bio)] = 0

# use florence soil: The Florence series consists of deep, well drained, moderately slowly permeable soils on uplands.
df_bio = df_bio[c(df_bio$SOILTYPE=="fl"),]

# extract the dates on which the measurements are made as well as the DOY and the year
dates_bio = as.Date(paste(df_bio$RECYEAR,df_bio$RECMONTH,df_bio$RECDAY,sep='-'),"%Y-%m-%d")
doy = as.numeric(format(dates_bio,"%j"))
year = as.numeric(format(dates_bio,"%Y"))

# make the variables human readable
grass = as.numeric(as.matrix(df_bio$LVGRASS))
forbs = as.numeric(as.matrix(df_bio$FORBS))
death_cur = as.numeric(as.matrix(df_bio$CUYRDEAD))
woody = as.numeric(as.matrix(df_bio$WOODY))

death_prev = as.numeric(as.matrix(df_bio$PRYRDEAD))
death_prev = as.numeric(c(death_prev[-1],NA))

# we will consider all biomass of perennial nature (death from this season or alive)
biomass = grass + forbs + death_cur
biomass = biomass * 10 # values are in g / 0.1 m2

# read in the modelled results
model= unlist(read.table('output/modelrun_01_fCover.txt'))

# read in the input data to extract the dates vector
dates =as.Date(paste(drivers[,1],drivers[,2],sep='-'),"%Y-%j")

bio_year = format(dates_bio,"%Y")
year = as.numeric(format(dates[order(dates)],"%Y"))
doy_drivers = as.numeric(format(dates[order(dates)],"%j"))
year_drivers = as.numeric(format(dates[order(dates)],"%Y"))
bio_doy = as.numeric( format(dates_bio,"%j"))

growth = model
growth_increase = c(diff(growth),NA)
growth_increase[which(growth_increase < 0) ] = NA

annual_model = by(growth,INDICES = list(year),function(x,...)sum(x[1:260],na.rm=T))

sums = by(biomass,INDICES=list(bio_year),FUN=mean,na.rm=T)
sds = by(biomass,INDICES=list(bio_year),FUN=sd,na.rm=T)

model_names = names(annual_model)
bio_names = names(sums)

pdf("output/Figure4.pdf",21,10)
par(mfrow=c(1,2),mar=c(5,5,3,1),tck=0.03,lwd=2.5,cex=2.5)
dd = cbind(sums,sds,annual_model[which(model_names %in% bio_names)])

plot(dd[,3],dd[,1],
xlab='Annual intergral of fCover',
col='olivedrab4',
ylab=expression("Biomass (g m" ^-2 *" yr" ^-1*")"),
pch=19,
bty='n',
xlim=c(60,120),
ylim=c(125,700),
yaxt='n',
xaxt='n',
xaxs='i',
yaxs='i')
axis(2,at=c(125,250,500),tck=0.03,lwd=2)
axis(1,tck=0.03,lwd=2)

# omit first 10 years as spinup
fit = lm(dd[,1]~dd[,3])
print(cor(dd[,3],dd[,1]))
print(summary(fit))
abline(fit,lty=2,col='grey')
coef = round(fit$coefficients,2)

text(65,550,expression("R" ^2 * "= 0.54; p < 0.001"),pos=4)
text(65,490,paste("y = ",coef[1]," + ",coef[2],"x",sep=""),pos=4)
legend('topright',legend="a",bty='n',cex=2)

##
par(mar=c(5,1,3,5))
p <- barplot(t(dd[,1]),ylim=c(125,700),xpd=FALSE,col='wheat',
xlab="Year",
ylab="",
border=NA,
yaxt='n')
axis(2,at=c(125,250,500),tck=0.03,labels=FALSE,lwd=2)
#mtext(expression("Biomass (g m" ^-2 *" yr" ^-1*")"),2,3,adj=0.2)

error.bar(p,dd[,1],dd[,2],col='wheat3')

par(new=TRUE)
lines(p,-28.97+dd[,3]*4.25,type='b',
xaxt='n',
yaxt='n',
col='olivedrab4',
lwd=3,
xlab='',
ylab='',
lty=2,
cex=0.8,
pch=19)
axis(4,at=c(125,250,500),labels=round(c(125,250,500)/4.25),tck=0.03,lwd=2)
mtext("Annual integral of fCover",4,3,cex=2.5)
legend('topright',legend="b",bty='n',cex=2)

graphics.off()

0 comments on commit 41e9c0a

Please sign in to comment.