Project

General

Profile

Download (8.5 KB) Statistics
| Branch: | Revision:
1
# R code to plot latitudinal profiles of (circular) mean aspect, along
2
# with both RMSE and (circular) correlation coefficients comparing fused
3
# layers with both the raw ASTER and with the Canada DEM
4
#
5
# Aspect layers were generated from the respect DEMs in this way:
6
#   $ gdaldem aspect -s 111120 <layer>.tif <layer>_a.tif
7
# ...where the default azimuthal behavior produces output values ranging
8
# from 0-360 where 0 is north, and proceeding clockwise
9
#
10
# For exploratory plotting, note the following (uses 'circular'
11
# package):
12
#  > cx <- circular(as.matrix(a.bg)[151,], units="degrees",
13
#      rotation="clock", zero=pi/2)
14
#  > rose.diag(cx, bins=8)
15
#  > points(mean.circular(cx, na.rm=TRUE), col="red")
16
#
17
# Jim Regetz
18
# NCEAS
19

    
20
library(raster)
21
library(circular)
22

    
23
datadir <- "/home/regetz/media/temp/terrain/aspect"
24

    
25
# load aspect rasters
26
a.aster <- raster(file.path(datadir, "aster_300straddle_a.tif"))
27
a.srtm <- raster(file.path(datadir, "srtm_150below_a.tif"))
28
a.uncor <- raster(file.path(datadir, "fused_300straddle_a.tif"))
29
a.enblend <- raster(file.path(datadir, "fused_300straddle_enblend_a.tif"))
30
a.bg <- raster(file.path(datadir, "fused_300straddle_blendgau_a.tif"))
31
a.can <- raster(file.path(datadir, "cdem_300straddle_a.tif"))
32

    
33
# extract raster latitudes for later
34
lats300 <- yFromRow(a.aster, 1:nrow(a.aster))
35
lats150 <- yFromRow(a.srtm, 1:nrow(a.srtm))
36

    
37
# initialize output pdf device driver
38
pdf("aspect-assessment.pdf", height=8, width=11.5)
39

    
40
#
41
# plot latitudinal profiles of mean aspect
42
#
43

    
44
# simple helper function to calculate row-wise means using circular
45
# mean, patterned after circ.mean in the CircStats package
46
rowMeansC <- function(r1, na.rm=TRUE) {
47
    m1 <- as.matrix(r1)
48
    m1[] <- (m1 * pi)/180
49
    sinr <- rowSums(sin(m1), na.rm=na.rm)
50
    cosr <- rowSums(cos(m1), na.rm=na.rm)
51
    cmeans <- atan2(sinr, cosr)
52
    (cmeans * 180)/pi
53
}
54

    
55
par(mfrow=c(2,2), omi=c(1,1,1,1))
56
ylim <- c(-180, 180)
57

    
58
plot(lats300, rowMeansC(a.can), type="l", yaxt="n",
59
    xlab="Latitude", ylab="Mean aspect", ylim=ylim)
60
axis(2, at=c(-180, -90, 0, 90, 180), labels=c("S", "W", "N", "E", "S"))
61
text(min(lats300), min(ylim)+0.5, pos=4, font=3, labels="Original DEMs")
62
lines(lats300, rowMeansC(a.aster), col="blue")
63
lines(lats150, rowMeansC(a.srtm), col="red")
64
legend("bottomright", legend=c("ASTER", "SRTM", "CDED"), col=c("blue",
65
    "red", "black"), lty=c(1, 1), bty="n")
66
abline(v=60, col="red", lty=2)
67
mtext(expression(paste("Latitudinal profiles of mean aspect (",
68
    136*degree, "W to ", 96*degree, "W)")), adj=0, line=2, font=2)
69

    
70
plot(lats300, rowMeansC(a.uncor), type="l", yaxt="n",
71
    xlab="Latitude", ylab="Mean aspect", ylim=ylim)
72
axis(2, at=c(-180, -90, 0, 90, 180), labels=c("S", "W", "N", "E", "S"))
73
text(min(lats300), min(ylim)+0.5, pos=4, font=3, labels="simple fused")
74
abline(v=60, col="red", lty=2)
75

    
76
plot(lats300, rowMeansC(a.enblend), type="l", yaxt="n",
77
    xlab="Latitude", ylab="Mean aspect", ylim=ylim)
78
axis(2, at=c(-180, -90, 0, 90, 180), labels=c("S", "W", "N", "E", "S"))
79
text(min(lats300), min(ylim)+0.5, pos=4, font=3, labels="multires spline")
80
abline(v=60, col="red", lty=2)
81

    
82
plot(lats300, rowMeansC(a.bg), type="l", yaxt="n",
83
    xlab="Latitude", ylab="Mean aspect", ylim=ylim)
84
axis(2, at=c(-180, -90, 0, 90, 180), labels=c("S", "W", "N", "E", "S"))
85
text(min(lats300), min(ylim)+0.5, pos=4, font=3, labels="gaussian blend")
86
abline(v=60, col="red", lty=2)
87

    
88

    
89
#
90
# plot latitudinal profiles of RMSE
91
#
92

    
93
# simple helper function to calculate row-wise RMSEs, accounting for the
94
# fact that aspect values are circular (0-360), so the difference
95
# between e.g. 5 and 355 should only be 10
96
rmse <- function(r1, r2, na.rm=TRUE, use) {
97
    diffs <- abs(as.matrix(r1) - as.matrix(r2))
98
    if (!missing(use)) diffs[!use] <- NA
99
    diffs[] <- ifelse(diffs>180, 360-diffs, diffs)
100
    sqrt(rowMeans(diffs^2, na.rm=na.rm))
101
}
102

    
103
par(mfrow=c(2,3), omi=c(1,1,1,1))
104

    
105
ylim <- c(0, 100)
106

    
107
# ...with respect to ASTER
108
plot(lats300, rmse(a.uncor, a.aster), type="l", xlab="Latitude",
109
    ylab="RMSE", ylim=ylim)
110
lines(lats150, rmse(crop(a.uncor, extent(a.srtm)), a.srtm), col="blue")
111
legend("topright", legend=c("ASTER", "SRTM"), col=c("black", "blue"),
112
    lty=c(1, 1), bty="n")
113
text(min(lats300), max(ylim)-5, pos=4, font=3, labels="simple fused")
114
abline(v=60, col="red", lty=2)
115
mtext(expression(paste(
116
    "Aspect discrepancies with respect to separate ASTER/SRTM components (",
117
    136*degree, "W to ", 96*degree, "W)")), adj=0, line=2, font=2)
118

    
119
plot(lats300, rmse(a.enblend, a.aster), type="l", xlab="Latitude",
120
    ylab="RMSE", ylim=ylim)
121
lines(lats150, rmse(crop(a.enblend, extent(a.srtm)), a.srtm), col="blue")
122
legend("topright", legend=c("ASTER", "SRTM"), col=c("black", "blue"),
123
    lty=c(1, 1), bty="n")
124
text(min(lats300), max(ylim)-5, pos=4, font=3, labels="multires spline")
125
abline(v=60, col="red", lty=2)
126

    
127
plot(lats300, rmse(a.bg, a.aster), type="l", xlab="Latitude",
128
    ylab="RMSE", ylim=ylim)
129
lines(lats150, rmse(crop(a.bg, extent(a.srtm)), a.srtm), col="blue")
130
legend("topright", legend=c("ASTER", "SRTM"), col=c("black", "blue"),
131
    lty=c(1, 1), bty="n")
132
text(min(lats300), max(ylim)-5, pos=4, font=3, labels="gaussian blend")
133
abline(v=60, col="red", lty=2)
134

    
135
# ...with respect to CDEM
136
plot(lats300, rmse(a.uncor, a.can), type="l", xlab="Latitude",
137
    ylab="RMSE", ylim=ylim)
138
text(min(lats300), max(ylim)-5, pos=4, font=3, labels="simple fused")
139
abline(v=60, col="red", lty=2)
140
mtext(expression(paste(
141
    "Aspect discrepancies with respect to Canada DEM (",
142
    136*degree, "W to ", 96*degree, "W)")), adj=0, line=2, font=2)
143

    
144
plot(lats300, rmse(a.enblend, a.can), type="l", xlab="Latitude",
145
    ylab="RMSE", ylim=ylim)
146
text(min(lats300), max(ylim)-5, pos=4, font=3, labels="multires spline")
147
abline(v=60, col="red", lty=2)
148

    
149
plot(lats300, rmse(a.bg, a.can), type="l", xlab="Latitude",
150
    ylab="RMSE", ylim=ylim)
151
text(min(lats300), max(ylim)-5, pos=4, font=3, labels="gaussian blend")
152
abline(v=60, col="red", lty=2)
153

    
154

    
155
#
156
# plot latitudinal profiles of correlation coefficients
157
#
158

    
159
# simple helper function to calculate row-wise *circular* correlation
160
# coefficients
161
corByLat <- function(r1, r2, rows) {
162
    if (missing(rows)) {
163
        rows <- 1:nrow(r1)
164
    }
165
    m1 <- circular(as.matrix(r1), units="degrees", rotation="clock")
166
    m2 <- circular(as.matrix(r2), units="degrees", rotation="clock")
167
    sapply(rows, function(row) {
168
        p <- cor.circular(m1[row,], m2[row,])
169
        if (is.null(p)) NA else p
170
        })
171
}
172

    
173
par(mfrow=c(2,3), omi=c(1,1,1,1))
174

    
175
ylim <- c(-1, 1)
176

    
177
# ...with respect to ASTER
178
plot(lats300, corByLat(a.uncor, a.aster), type="l", xlab="Latitude",
179
    ylab="Circular correlation", ylim=ylim)
180
lines(lats150, corByLat(crop(a.uncor, extent(a.srtm)), a.srtm), col="blue")
181
legend("bottomright", legend=c("ASTER", "SRTM"), col=c("black", "blue"),
182
    lty=c(1, 1), bty="n")
183
text(min(lats300), min(ylim), pos=4, font=3, labels="simple fused")
184
abline(v=60, col="red", lty=2)
185
mtext(expression(paste(
186
    "Aspect correlations with respect to separate ASTER/SRTM components (",
187
    136*degree, "W to ", 96*degree, "W)")), adj=0, line=2, font=2)
188

    
189
plot(lats300, corByLat(a.enblend, a.aster), type="l", xlab="Latitude",
190
    ylab="Circular correlation", ylim=ylim)
191
lines(lats150, corByLat(crop(a.enblend, extent(a.srtm)), a.srtm), col="blue")
192
legend("bottomright", legend=c("ASTER", "SRTM"), col=c("black", "blue"),
193
    lty=c(1, 1), bty="n")
194
text(min(lats300), min(ylim), pos=4, font=3, labels="multires spline")
195
abline(v=60, col="red", lty=2)
196

    
197
plot(lats300, corByLat(a.bg, a.aster), type="l", xlab="Latitude",
198
    ylab="Circular correlation", ylim=ylim)
199
lines(lats150, corByLat(crop(a.bg, extent(a.srtm)), a.srtm), col="blue")
200
legend("bottomright", legend=c("ASTER", "SRTM"), col=c("black", "blue"),
201
    lty=c(1, 1), bty="n")
202
text(min(lats300), min(ylim), pos=4, font=3, labels="gaussian blend")
203
abline(v=60, col="red", lty=2)
204

    
205
# ...with respect to CDEM
206
plot(lats300, corByLat(a.uncor, a.can), type="l", xlab="Latitude",
207
    ylab="Circular correlation", ylim=ylim)
208
text(min(lats300), min(ylim), pos=4, font=3, labels="simple fused")
209
abline(v=60, col="red", lty=2)
210
mtext(expression(paste(
211
    "Aspect correlations with respect to Canada DEM (",
212
    136*degree, "W to ", 96*degree, "W)")), adj=0, line=2, font=2)
213

    
214
plot(lats300, corByLat(a.enblend, a.can), type="l", xlab="Latitude",
215
    ylab="Circular correlation", ylim=ylim)
216
text(min(lats300), min(ylim), pos=4, font=3, labels="multires spline")
217
abline(v=60, col="red", lty=2)
218

    
219
plot(lats300, corByLat(a.bg, a.can), type="l", xlab="Latitude",
220
    ylab="Circular correlation", ylim=ylim)
221
text(min(lats300), min(ylim), pos=4, font=3, labels="gaussian blend")
222
abline(v=60, col="red", lty=2)
223

    
224
# close pdf device driver
225
dev.off()
(4-4/23)