Revision bd0f46cc7c6441f34a77a193645fcfcb5741d583 authored by Diethelm Wuertz on 08 August 1977, 00:00:00 UTC, committed by Gabor Csardi on 08 August 1977, 00:00:00 UTC
0 parent
A1-evPlots.R
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU Library General
# Public License along with this library; if not, write to the
# Free Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
# Copyrights (C)
# this R-port:
# by Diethelm Wuertz <wuertz@itp.phys.ethz.ch>
# for the code accessed (or partly included) from other R-ports:
# R: see R's copyright and license file
# evir: original S functions (EVIS) by Alexander McNeil <mcneil@math.ethz.ch>
# R port by Alec Stephenson <a.stephenson@lancaster.ac.uk>
# ismev: Original S functions by Stuart Coles <Stuart.Coles@bristol.ac.uk>
# R port/documentation by Alec Stephenson <a.stephenson@lancaster.ac.uk>
# evd: Alec Stephenson <alec_stephenson@hotmail.com>
################################################################################
# FUNCTION DESCRIPTION:
# emdPlot Plots empirical distribution function
# qqPlot Creates a quantile-quantile plot
# qqbayesPlot Creates qq-Plot with 95 percent intervals
# qPlot Creates exploratory QQ plot for EV analysis
# mePlot Creates a sample mean excess plot
# mxfPlot Plots the mean excess function
# mrlPlot Returns a mean residual life plot with confidence levels
# recordsPlot Plots records development
# ssrecordsPlot Plots records development of data subsamples
# msratioPlot Plots ratio of maximums and sums
# xacfPlot Plots autocorrelations of exceedences
# interactivePlot Plots several graphs interactively
# gridVector Creates from two vectors rectangular grid points
################################################################################
emdPlot =
function(x, doplot = TRUE, plottype = c("", "x", "y", "xy"),
labels = TRUE, ...)
{ # A function imported from R-package evir
# Description:
# Plots empirical distribution function
# Arguments:
# plottype - which axes should be on a log scale:
# "x" denotes x-axis only; "y" denotes y-axis only,
# "xy" || "yx" both axes, "" denotes neither of the
# axis
# FUNCTION:
# Settings:
alog = plottype[1]
# Convert x to a vector, if the input is a data.frame.
if (is.data.frame(x)) x = x[,1]
xs = x = sort(as.numeric(x))
ys = y = 1 - ppoints(x)
if (plottype == "x") {
xs = x[x > 0]
ys = y[x > 0] }
if (plottype == "y") {
xs = x[y > 0]
ys = y[y > 0] }
if (plottype == "xy") {
xs = x[x > 0 & y > 0]
ys = y[x > 0 & y > 0] }
# Plot:
if (doplot) {
if (labels) {
xlab = "x"
ylab = "1-F(x)"
main = "Empirical Distribution" }
else {
xlab = ""
ylab = ""
main = "" }
plot(xs, ys, log = alog, xlab = xlab, ylab = ylab, main = main, ...)
if (labels) grid()
}
# Result:
result = data.frame(x, y)
# Return Value:
if (doplot) return(invisible(result)) else return(result)
}
# ------------------------------------------------------------------------------
qqPlot =
function (x, doplot = TRUE, labels = TRUE, ...)
{ # A function written by Diethelm Wuertz
# Description:
# Creates Quantile-Quantile Plot
# FUNCTION:
# Convert x to a vector, if the input is a data.frame.
if (is.data.frame(x)) x = x[,1]
# Plot:
if (doplot) {
if (labels) {
xlab = "Normal Quantiles"
ylab = "Empirical Quantiles"
main = "Normal QQ-Plot"
print(main) }
else {
xlab = ""
ylab = ""
main = "" }
qqnorm(x, xlab = xlab, ylab = ylab, main = main, ...)
qqline(x)
if (labels) grid()
}
# Return Value:
if (doplot) return(invisible(x)) else return(x)
}
# ------------------------------------------------------------------------------
qqbayesPlot =
function(x, doplot = TRUE, labels = TRUE, ...)
{ # A function implemented by Diethelm Wuertz
# Description:
# Example of a Normal quantile plot of data x to provide a visual
# assessment of its conformity with a normal (data is standardised
# first).
# Details:
# The ordered data values are posterior point estimates of the
# underlying quantile function. So, if you plot the ordered data
# values (y-axis) against the exact theoretical quantiles (x-axis),
# you get a scatter that should be close to a straight line if the
# data look like a random sample from the theoretical distribution.
# This function chooses the normal as the theory, to provide a
# graphical/visual assessment of how normal the data appear.
# To help with assessing the relevance of sampling variability on
# just "how close" to the normal the data appears, we add (very)
# approximate posterior 95% intervals for the uncertain quantile
# function at each point (Based on approximate theory) .
# Author:
# Prof. Mike West, mw@stat.duke.edu
# Note:
# Source from
# http://www.stat.duke.edu/courses/Fall99/sta290/Notes/
# FUNCTION:
# Settings:
mydata = x
n = length(mydata)
p = (1:n)/(n+1)
x = (mydata-mean(mydata))/sqrt(var(mydata))
x = sort(x)
z = qnorm(p)
# Plot:
if (doplot) {
if (labels) {
xlab = "Standard Normal Quantiles"
ylab = "Ordered Data"
main = "Normal QQ-Plot with 95% Intervals" }
else {
xlab = ""
ylab = ""
main = "" }
plot(z, x, xlab = xlab, ylab = ylab, main = main, ...)
abline(0, 1, col = "steelblue3")
if (labels) grid()
}
# 95% Intervals:
s = 1.96*sqrt(p*(1-p)/n)
pl = p-s; i = pl<1&pl>0
lower = quantile(x, probs = pl[i])
if (doplot) lines(z[i], lower, col = 3)
pl = p+s; i = pl < 1 & pl > 0
upper = quantile(x, probs = pl[i])
if (doplot) lines(z[i], upper, col = 3)
# Result:
result = data.frame(lower, upper)
# Return Value:
if (doplot) return(invisible(result)) else return(result)
}
# ------------------------------------------------------------------------------
qPlot =
function(x, xi = 0, trim = NA, threshold = NA, doplot = TRUE,
labels = TRUE, ...)
{ # A function imported from R-package evir
# Description:
# Creates an exploratory QQplot for Extreme Value Analysis.
# FUNCTION:
# Settings:
line = TRUE
# Convert x to a vector, if the input is a data.frame.
if(is.data.frame(x)) x = x[,1]
x = as.numeric(x)
if (!is.na(threshold)) x = x[x >= threshold]
if (!is.na(trim)) x = x[x < trim]
if (xi == 0) {
y = qexp(ppoints(x)) }
if( xi != 0) {
y = qgpd(ppoints(x), xi = xi) }
# Plot:
if (doplot) {
if (labels) {
xlab = "Ordered Data"
ylab = "Quantiles"
if (xi == 0) {
ylab = paste("Exponential", ylab) }
if (xi != 0) {
ylab = paste("GPD(xi=", xi, ") ", ylab, sep = "") }
main = "Exploratory QQ Plot" }
else {
xlab = ""
ylab = ""
main = "" }
plot(sort(x), y, xlab = xlab, ylab = ylab, main = main, ...)
if (line) abline(lsfit(sort(x), y))
if (labels) grid()
}
# Result:
result = data.frame(x = sort(x), y)
# Return Value:
if (doplot) return(invisible(result)) else return(result)
}
# ------------------------------------------------------------------------------
mxfPlot =
function (x, tail = 0.05, doplot = TRUE, labels = TRUE, ...)
{ # A function written by D. Wuertz
# Description:
# Creates a simple mean excess function plot.
# FUNCTION:
# Convert x to a vector, if the input is a data.frame.
if(is.data.frame(x)) x = x[,1]
u = rev(sort(x))
n = length(x)
u = u[1:floor(tail*n)]
n = length(u)
e = (cumsum(u)-(1:n)*u)/(1:n)
# Plot
if (doplot) {
if (labels) {
xlab = "Threshold: u"
ylab = "Mean Excess: e"
main = "Mean Excess Function" }
else {
xlab = ""
ylab = ""
main = "" }
plot (u, e, xlab = xlab, ylab = ylab, main = main, ...)
if (labels) grid()
}
# Result:
result = data.frame(threshold = u, excess = e)
# Return Values:
if (doplot) return(invisible(result)) else return(result)
}
# ------------------------------------------------------------------------------
mrlPlot =
function(x, conf = 0.95, umin = NA, umax=NA, nint = 100,
doplot = TRUE, plottype = c("autoscale", ""), labels = TRUE, ...)
{ # A function implemented by Diethelm Wuertz
# Description:
# Create a mean residual life plot with
# confidence intervals.
# Note:
# "autoscale" added by DW.
# References:
# A function originally written by S. Coles
# FUNCTION:
# Settings:
plottype = plottype[1]
if (plottype == "autoscale") {
autoscale = TRUE }
else {
autoscale = FALSE }
# Convert x to a vector, if the input is a data.frame.
if (is.data.frame(x)) x = x[,1]
if (is.na(umin)) umin = mean(x)
if (is.na(umax)) umax = max(x)
sx = xu = xl = rep(NA, nint)
u = seq(umin, umax, length = nint)
for(i in 1:nint) {
x = x[x >= u[i]]
sx[i] = mean(x - u[i])
sdev = sqrt(var(x))
n = length(x)
xu[i] = sx[i] + (qnorm((1 + conf)/2) * sdev)/sqrt(n)
xl[i] = sx[i] - (qnorm((1 + conf)/2) * sdev)/sqrt(n) }
# Plot:
if (doplot) {
if (labels) {
xlab = "Threshold: u"
ylab = "Mean Excess: e"
main = "Mean Residual Live Plot" }
else {
xlab = ""
ylab = ""
main = "" }
if (autoscale) {
ylim = c(min(xl[!is.na(xl)]), max(xu[!is.na(xu)]))
plot(u, sx, type = "l", lwd = 2, xlab = xlab,
ylab = ylab, ylim = ylim, main = main, ...) }
else {
plot(u[!is.na(xl)], sx[!is.na(xl)], type = "l",
lwd = 2, xlab = xlab, ylab = ylab, main = main, ...) }
lines(u[!is.na(xl)], xl[!is.na(xl)], col = "steelblue3")
lines(u[!is.na(xu)], xu[!is.na(xu)], col = "steelblue3")
if (labels) grid()
}
# Result
result = data.frame(threshold = u, mrl = sx)
# Return Value:
if (doplot) return(invisible(result)) else return(result)
}
# ------------------------------------------------------------------------------
mePlot =
function(x, doplot = TRUE, labels = TRUE, ...)
{ # A function implemented by Diethelm Wuertz
# Description:
# Create a Mean Excess Plot
# Reference:
# A function imported from R-package evir
# FUNCTION:
# Settings:
omit = 0
# Internal Function:
myrank = function(x, na.last = TRUE){
ranks = sort.list(sort.list(x, na.last = na.last))
if(is.na(na.last))
x = x[!is.na(x)]
for(i in unique(x[duplicated(x)])) {
which = x == i & !is.na(x)
ranks[which] = max(ranks[which]) }
ranks }
# Convert x to a vector, if the input is a data.frame.
if(is.data.frame(x)) x = x[,1]
x = as.numeric(x)
n = length(x)
x = sort(x)
n.excess = unique(floor(length(x) - myrank(x)))
points = unique(x)
nl = length(points)
n.excess = n.excess[-nl]
points = points[-nl]
excess = cumsum(rev(x))[n.excess] - n.excess * points
y = excess/n.excess
xx = points[1:(nl-omit)]
yy = y[1:(nl-omit)]
# Plot:
if (doplot) {
if (labels) {
xlab = "Threshold: u"
ylab = "Mean Excess: e"
main = "Mean Excess Plot" }
else {
xlab = ""
ylab = ""
main = "" }
plot(xx, yy, xlab = xlab, ylab = ylab, main = main, ...)
if (labels) grid()
}
# Results:
result = data.frame(threshold = xx, me = yy)
# Return Value:
if (doplot) return(invisible(result)) else return(result)
}
# -----------------------------------------------------------------------------
recordsPlot =
function(x, conf = 0.95, doplot = TRUE, labels = TRUE, ...)
{ # A function implemented by Diethelm Wuertz
# Description:
# Creates a records plot.
# Note:
# A function imported from R-package evir,
# original name in EVIR: records
# FUNCTION:
# Settings:
conf.level = conf
# Convert x to a vector, if the input is a data.frame.
if (is.data.frame(x)) x = x[,1]
# Records:
record = cummax(x)
expected = cumsum(1/(1:length(x)))
se = sqrt(expected - cumsum(1/((1:length(x))^2)))
trial = (1:length(x))[!duplicated(record)]
record = unique(record)
number = 1:length(record)
expected = expected[trial]
se = se[trial]
# Plot:
if (doplot) {
if (labels) {
xlab = "Trials"
ylab = "Records"
main = "Plot of Record Development" }
else {
xlab = ""
ylab = ""
main = "" }
ci = qnorm(0.5 + conf.level/2)
upper = expected + ci * se
lower = expected - ci * se
lower[lower < 1] = 1
yr = range(upper, lower, number)
plot(trial, number, log = "x", ylim = yr,
xlab = xlab, ylab = ylab, main = main, ...)
lines(trial, expected)
lines(trial, upper, lty = 2)
lines(trial, lower, lty = 2)
if (labels) grid()
}
# Result:
result = data.frame(number, record, trial, expected, se)
# Return Value:
if (doplot) return(invisible(result)) else return(result)
}
# ------------------------------------------------------------------------------
ssrecordsPlot =
function (x, subsamples = 10, doplot = TRUE, plottype = c("lin", "log"),
labels = TRUE, ...)
{ # A function implemented by Diethelm Wuertz
# Description:
# Creates a plot of records on subsamples.
# note:
# Changes:
# 2003/09/06 - argument list made consistent
# FUNCTION:
# Convert x to a vector, if the input is a data.frame.
if(is.data.frame(x)) x = x[,1]
# Plot type:
plottype = plottype[1]
# Records:
save = x
cluster = floor(length(save)/subsamples)
records = c()
for (i in 1:subsamples) {
x = save[((i-1)*cluster+1):(i*cluster)]
y = 1:length(x)
u = x[1]
v = x.records = 1
while (!is.na(v)) {
u = x[x > u][1]
v = y[x > u][1]
if(!is.na(v)) x.records = c(x.records, v) }
if (i == 1) {
nc = 1:length(x)
csmean = cumsum(1/nc)
cssd = sqrt(cumsum(1/nc-1/(nc*nc)))
ymax = csmean[length(x)]+2*cssd[length(x)]
# Plot:
if (doplot) {
if (plottype == "log") nc = log(nc)
if (labels) {
if (plottype == "lin") xlab = "n"
if (plottype == "log") xlab = "log(n)"
ylab = "N(n)" }
main = "Subsample Records Plot"
plot (nc, csmean+cssd, type = "l", ylim = c(0, ymax),
xlab = xlab, ylab = ylab, main = main, ...) }
else {
plot (nc, csmean+cssd, type = "l", ylim = c(0, ymax),
...) }
lines(nc, csmean)
lines(nc, csmean-cssd) }
y.records = 1:length(x.records)
x.records = x.records[y.records < ymax]
if (doplot) {
if (plottype == "log") x.records = log(x.records)
points(x.records, y.records[y.records<ymax], col=i) }
records[i] = y.records[length(y.records)]}
# Result:
subsample = 1:subsamples
result = data.frame(subsample, records)
# Return Value:
if (doplot) return(invisible(result)) else return(result)
}
# ------------------------------------------------------------------------------
msratioPlot =
function (x, p = 1:4, doplot = TRUE, plottype = c("autoscale", ""),
labels = TRUE, ...)
{ # A function implemented by Diethelm Wuertz
# Description:
# Creates a Plot of maximum and sum ratio.
# FUNCTION:
# Settings:
plottype = plottype[1]
if (plottype == "autoscale") {
autoscale = TRUE }
else {
autoscale = FALSE }
if (autoscale) ylim = c(0,1)
# Convert x to a vector, if the input is a data.frame.
if(is.data.frame(x)) x = x[,1]
# Plot:
if (doplot) {
if (labels) {
xlab = "Trials"
ylab = "Records"
main = "Plot of Record Development" }
else {
xlab = ""
ylab = ""
main = "" }
if (autoscale) {
plot(c(0, length(x)), y = ylim, xlab = xlab,
ylab = ylab, main = main, type = "n", ...) }
else {
plot(c(0, length(x)), xlab = xlab,
ylab = ylab, main = main, type = "n", ...) }
if (labels) grid()
}
# Color numbering:
i = 1
# Suppress warnings for points outside the frame:
ratios = matrix(rep(0, times=length(x)*length(p)), byrow=TRUE,
ncol=length(p))
if (doplot) par(err=-1)
# Loop over all exponents p:
for (q in p) {
rnp = cummax(abs(x)^q) / cumsum(abs(x)^q)
i = i + 1
ratios[,q] = rnp
if (doplot) lines (rnp, col=i) }
# Result:
result = data.frame(ratios)
# Return Value:
if (doplot) return(invisible(result)) else return(result)
}
# ------------------------------------------------------------------------------
xacfPlot =
function(x, threshold = 0.95, lag.max = 15, doplot = TRUE, ...)
{ # A function implemented by Diethelm Wuertz
# Description:
# Creates plots of exceedences, one for the
# heights and one for the distances.
# FUNCTION:
# Settings:
# Sorry, user specified labels not yet implemented.
labels = TRUE
if (labels) {
xlab = c("Index", "Lag")
ylab = c("Heights", "Distances", "ACF")
main = c("Heights over Threshold", "Distances between Heights",
"Series Heights", "Series Distances") }
# Convert x to a vector, if the input is a data.frame.
if (is.data.frame(x)) x = x[,1]
# Heights/Distances
threshold = sort(x)[round(threshold*length(x))]
Heights = (x-threshold)[(x-threshold)>0]
Distances = diff((1:length(x))[(x-threshold)>0])
# Plot:
if (doplot) {
plot (Heights, type="h", xlab = xlab[1], ylab = ylab[1],
main = main[1], ...)
plot (Distances,type="h", xlab = xlab[1], ylab = ylab[2],
main = main[2], ...) }
# Correlations:
Heights = as.vector(acf(Heights, lag.max=lag.max, plot = doplot,
xlab = xlab[2], ylab = ylab[3], main = main[3], ...)$acf)
Distances = as.vector(acf(Distances, lag.max=lag.max, plot = doplot,
xlab = xlab[2], ylab = ylab[3], main = main[4], ...)$acf)
# Result:
lag = as.vector(0:(lag.max))
result = data.frame(lag, Heights, Distances)
# Return Value:
if (doplot) return(invisible(result)) else return(result)
}
# ******************************************************************************
interactivePlot =
function(x, choices = paste("Plot", 1:9),
plotFUN = paste("plot.", 1:9, sep = ""), which = "all", ...)
{ # A function implemented by Diethelm Wuertz
# Description:
# Plot method for an object of class "template".
# Arguments:
# x - an object to be plotted
# choices - the character string for the choice menu
# plotFUN - the names of the plot functions
# which - plot selection, which graph should be
# displayed. If a character string named "ask" the
# user is interactively asked which to plot, if
# a logical vector of length N, those plots which
# are set "TRUE" are displayed, if a character string
# named "all" all plots are displayed.
# Note:
# At maximum 9 plots are supported.
# FUNCTION:
# Some cecks:
if (length(choices) != length(plotFUN))
stop("Arguments choices and plotFUN must be of same length.")
if (length(which) > length(choices))
stop("Arguments which has incoorect length.")
if (length(which) > length(plotFUN))
stop("Arguments which has incorrect length.")
if (length(choices) > 9)
stop("Sorry, only 9 plots at max are supported.")
# Internal "askPlot" Function:
multPlot = function (x, choices, ...) {
# Selective Plot:
selectivePlot = function (x, choices, FUN, which){
# Internal Function:
askPlot = function (x, choices, FUN) {
# Pick and Plot:
pick = 1; n.plots = length(choices)
while (pick > 0) { pick = menu (
choices = paste("plot:", choices),
title = "\nMake a plot selection (or 0 to exit):")
if (pick > 0) match.fun(FUN[pick])(x) } }
if (as.character(which[1]) == "ask") {
askPlot(x, choices = choices, FUN = FUN, ...) }
else {
for (i in 1:n.plots) if (which[i]) match.fun(FUN[i])(x) }
invisible() }
# match Functions, up to nine ...
if (length(plotFUN) < 9) plotFUN =
c(plotFUN, rep(plotFUN[1], times = 9 - length(plotFUN)))
plot.1 = match.fun(plotFUN[1]); plot.2 = match.fun(plotFUN[2])
plot.3 = match.fun(plotFUN[3]); plot.4 = match.fun(plotFUN[4])
plot.5 = match.fun(plotFUN[5]); plot.6 = match.fun(plotFUN[6])
plot.7 = match.fun(plotFUN[7]); plot.8 = match.fun(plotFUN[8])
plot.9 = match.fun(plotFUN[9])
pick = 1
while (pick > 0) { pick = menu (
### choices = paste("plot:", choices),
choices = paste(" ", choices),
title = "\nMake a plot selection (or 0 to exit):")
# up to 9 plot functions ...
switch (pick, plot.1(x), plot.2(x), plot.3(x), plot.4(x),
plot.5(x), plot.6(x), plot.7(x), plot.8(x), plot.9(x) ) } }
# Plot:
if (which[1] == "all") which = rep(TRUE, times = length(choices))
if (which[1] == "ask") {
multPlot(x, choices, ...) }
else {
for ( i in 1:length(which) ) {
FUN = match.fun(plotFUN[i])
if (which[i]) FUN(x) } }
# Return Value:
invisible(x)
}
# ******************************************************************************
gridVector =
function(x, y)
{ # A function implemented by Diethelm Wuertz, GPL
# Description:
# Creates from two vectors x and y all grid points
# Details:
# The two vectors x and y span a rectangular grid with nx=length(x)
# times ny=length(y) points which are returned as a matrix of size
# (nx*ny) times 2.
# Arguments:
# x, y - two numeric vectors of length m and n which span the
# rectangular grid of size m times n.
# Value:
# returns a list with two elements X and Y each of length m
# times n
# Example:
# > gridVector(1:3, 1:2)
# [,1] [,2]
# [1,] 1 1
# [2,] 2 1
# [3,] 3 1
# [4,] 1 2
# [5,] 2 2
# [6,] 3 2
# FUNCTION:
# Prepare for Input:
nx = length(x)
ny = length(y)
xoy = cbind(rep(x, ny), as.vector(matrix(y, nx, ny, byrow = TRUE)))
X = matrix(xoy, nx * ny, 2, byrow = FALSE)
# Return Value:
list(X = X[,1], Y = X[,2])
}
# ******************************************************************************
Computing file changes ...