I was building a custom function that automatically add legends to a plot.xts object.
Code here:
library(xts)
library(PerformanceAnalytics)
data(edhec)
R <- edhec[,1:4]
chartS <- function(R,
y = NULL,
multi.panel = FALSE,
type = "l",
yaxis.same = TRUE,
event.lines = NULL,
event.labels = NULL,
event.col = 1,
event.offset = 1.2,
event.pos = 2,
event.srt = 90,
event.cex = 1.5,
lty = 1,
lwd = 2,
legend.loc = NULL,
legend.names = NULL, ...) {
plot.xts(R, y = y, multi.panel = multi.panel,
type = type, yaxis.same = yaxis.same, lty = lty, lwd = lwd, ...)
plot_object <- xts:::current.xts_chob()
columns <- plot_object$Env$xdata
columnnames <- plot_object$Env$column_names
if(!is.null(event.lines)) {
# error occurred
addEventLines(xts(event.labels, as.Date(event.lines)),
offset = event.offset, pos = event.pos,
srt = event.srt, cex = event.cex, col = event.col, ...)
}
if(is.null(legend.loc))
legend.loc <- "topright"
if(is.null(legend.names))
legend.names <- columnnames
if(!multi.panel)
addLegend(legend.loc, legend.names, lty = lty, lwd = lwd, ...)
}
# chartS(R)
# chartS(R, lty = 1:4)
chartS(R, multi.panel = TRUE)
I failed to plot multiple windows with no messages when I set multi.panel = TRUE. But if I remove codes below plot.xts or move them to above plot.xts, it works again.
Remove codes below plot.xts
library(xts)
library(PerformanceAnalytics)
data(edhec)
R <- edhec[,1:4]
chartS <- function(R,
y = NULL,
multi.panel = FALSE,
type = "l",
yaxis.same = TRUE,
event.lines = NULL,
event.labels = NULL,
event.col = 1,
event.offset = 1.2,
event.pos = 2,
event.srt = 90,
event.cex = 1.5,
lty = 1,
lwd = 2,
legend.loc = NULL,
legend.names = NULL, ...) {
plot.xts(R, y = y, multi.panel = multi.panel,
type = type, yaxis.same = yaxis.same, lty = lty, lwd = lwd, ...)
}
# chartS(R)
# chartS(R, lty = 1:4)
chartS(R, multi.panel = TRUE)
Move codes to be above plot.xts
library(xts)
library(PerformanceAnalytics)
data(edhec)
R <- edhec[,1:4]
chartS <- function(R,
y = NULL,
multi.panel = FALSE,
type = "l",
yaxis.same = TRUE,
event.lines = NULL,
event.labels = NULL,
event.col = 1,
event.offset = 1.2,
event.pos = 2,
event.srt = 90,
event.cex = 1.5,
lty = 1,
lwd = 2,
legend.loc = NULL,
legend.names = NULL, ...) {
columns <- ncol(R)
columnnames <- colnames(R)
if(!is.null(event.lines)) {
# error occurred
addEventLines(xts(event.labels, as.Date(event.lines)),
offset = event.offset, pos = event.pos,
srt = event.srt, cex = event.cex, col = event.col, ...)
}
if(is.null(legend.loc))
legend.loc <- "topright"
if(is.null(legend.names))
legend.names <- columnnames
if(!multi.panel)
addLegend(legend.loc, legend.names, lty = lty, lwd = lwd, ...)
plot.xts(R, y = y, multi.panel = multi.panel,
type = type, yaxis.same = yaxis.same, lty = lty, lwd = lwd, ...)
}
# chartS(R)
# chartS(R, lty = 1:4)
chartS(R, multi.panel = TRUE)
Any suggestions?
You need to keep track of the plot object you're building, and return it so it auto-prints. You should also not access unexported objects (xts:::current.xts_chob()) because there's no guarantee they will remain consistent across versions.
chartS <-
function(R, y = NULL, multi.panel = FALSE, type = "l", yaxis.same = TRUE,
event.lines = NULL, event.labels = NULL, event.col = 1,
event.offset = 1.2, event.pos = 2, event.srt = 90, event.cex = 1.5,
lty = 1, lwd = 2, legend.loc = NULL, legend.names = NULL, ...)
{
plot_object <- plot.xts(R, y = y, multi.panel = multi.panel, type = type,
yaxis.same = yaxis.same, lty = lty, lwd = lwd, ...)
columns <- plot_object$Env$xdata
columnnames <- plot_object$Env$column_names
if(!is.null(event.lines)) {
plot_object <-
addEventLines(xts(event.labels, as.Date(event.lines)), offset = event.offset,
pos = event.pos, srt = event.srt, cex = event.cex, col = event.col, ...)
}
if(is.null(legend.loc))
legend.loc <- "topright"
if(is.null(legend.names))
legend.names <- columnnames
if(!multi.panel)
plot_object <- addLegend(legend.loc, legend.names, lty = lty, lwd = lwd, ...)
return(plot_object)
}
Related
I am using a loop for plotting the histogram, group by different values of column_a at once which works perfectly fine. Here's the code:
par(ask=F)
for (i in unique(Data$column_a)) {
dat <- Data[Data$column_a== i, ]
plotdist(dat$count,histo = TRUE, demp = TRUE, discrete = T,
pch = 16, col = "dodgerblue1")
}
The only problem is that I cannot label each figure relative to column_a value to differentiate the figures from on another.
Thanks in advance for the help.
my data consists of number of losses with the column name of "count" with 3 distinct value in column_a(R,I,F)). and I want to plot the histogram of number of losses for these three values.
A somewhat hacky solution would be to alter the function itself.
Below is the alteret function, which uncludes the title argument (and only works for the configuration you had in your question!)
plotdist_alt <- function (data, distr, para, histo = TRUE, breaks = "default",
demp = FALSE, discrete, title = "default", ...)
{
def.par <- par(no.readonly = TRUE)
if (missing(data) || !is.vector(data, mode = "numeric"))
stop("data must be a numeric vector")
if ((missing(distr) & !missing(para)) || (missing(distr) &
!missing(para)))
stop("distr and para must defined")
if (!histo & !demp)
stop("one the arguments histo and demp must be put to TRUE")
xlim <- c(min(data), max(data))
s <- sort(data)
n <- length(data)
if (missing(distr)) {
par(mfrow = c(1, 2))
if (missing(discrete))
discrete <- FALSE
if (!discrete) {
obsp <- ppoints(s)
if (histo) {
if (demp) {
if (breaks == "default")
h <- hist(data, freq = FALSE, xlab = "Data",
main = "Empirical density", ...)
else h <- hist(data, freq = FALSE, xlab = "Data",
main = "Empirical density", breaks = breaks,
...)
lines(density(data)$x, density(data)$y, lty = 2,
col = "black")
}
else {
if (breaks == "default")
h <- hist(data, freq = FALSE, xlab = "Data",
main = "Histogram", ...)
else h <- hist(data, freq = FALSE, xlab = "Data",
main = "Histogram", breaks = breaks,
...)
}
}
else {
h <- hist(data, freq = FALSE, xlab = "Data",
main = "Histogram", plot = FALSE, ...)
plot(density(data)$x, density(data)$y, lty = 1,
col = "black", type = "l", xlab = "Data",
main = paste("Empirical density"), ylab = "Density",
...)
}
plot(s, obsp, main = paste("Cumulative distribution"),
xlab = "Data", xlim = c(h$breaks[1], h$breaks[length(h$breaks)]),
ylab = "CDF", ...)
}
else {
if (breaks != "default")
warning("Breaks are\tnot taken into account for discrete data")
t <- table(data)
xval <- as.numeric(names(t))
ydobs <- as.vector(t)/n
ydmax <- max(ydobs)
plot(xval, ydobs, type = "h", xlim = xlim,
ylim = c(0, ydmax), main = paste0("Empirical distribution ", title),
xlab = "Data", ylab = "Density",
...)
ycdfobs <- cumsum(ydobs)
plot(xval, ycdfobs, type = "p", xlim = xlim,
ylim = c(0, 1), main = paste0("Empirical CDFs ", title),
xlab = "Data", ylab = "CDF", ...)
}
}
else {
if (!is.character(distr))
distname <- substring(as.character(match.call()$distr),
2)
else distname <- distr
if (!is.list(para))
stop("'para' must be a named list")
ddistname <- paste("d", distname, sep = "")
if (!exists(ddistname, mode = "function"))
stop(paste("The ", ddistname, " function must be defined"))
pdistname <- paste("p", distname, sep = "")
if (!exists(pdistname, mode = "function"))
stop(paste("The ", pdistname, " function must be defined"))
qdistname <- paste("q", distname, sep = "")
if (!exists(qdistname, mode = "function"))
stop(paste("The ", qdistname, " function must be defined"))
densfun <- get(ddistname, mode = "function")
nm <- names(para)
f <- formals(densfun)
args <- names(f)
m <- match(nm, args)
if (any(is.na(m)))
stop(paste("'para' specifies names which are not arguments to ",
ddistname))
if (missing(discrete)) {
if (is.element(distname, c("binom", "nbinom",
"geom", "hyper", "pois")))
discrete <- TRUE
else discrete <- FALSE
}
if (!discrete) {
par(mfrow = c(2, 2))
obsp <- ppoints(s)
if (breaks == "default")
h <- hist(data, plot = FALSE)
else h <- hist(data, breaks = breaks, plot = FALSE,
...)
xhist <- seq(min(h$breaks), max(h$breaks), length = 1000)
yhist <- do.call(ddistname, c(list(xhist), as.list(para)))
if (length(yhist) != length(xhist))
stop("problem when computing densities.")
ymax <- ifelse(is.finite(max(yhist)), max(max(h$density),
max(yhist)), max(h$density))
if (histo) {
hist(data, freq = FALSE, xlab = "Data",
ylim = c(0, ymax), breaks = h$breaks, main = paste("Empirical and theoretical dens."),
...)
if (demp) {
lines(density(data)$x, density(data)$y, lty = 2,
col = "black")
}
}
else plot(density(data)$x, density(data)$y, lty = 2,
col = "black", type = "l", xlab = "Data",
main = paste("Empirical and theoretical dens."),
ylab = "Density", xlim = c(min(h$breaks),
max(h$breaks)), ...)
if (demp)
legend("topright", bty = "n", lty = c(2,
1), col = c("black", "red"), legend = c("empirical",
"theoretical"), bg = "white", cex = 0.7)
lines(xhist, yhist, lty = 1, col = "red")
theoq <- do.call(qdistname, c(list(obsp), as.list(para)))
if (length(theoq) != length(obsp))
stop("problem when computing quantities.")
plot(theoq, s, main = " Q-Q plot", xlab = "Theoretical quantiles",
ylab = "Empirical quantiles", ...)
abline(0, 1)
xmin <- h$breaks[1]
xmax <- h$breaks[length(h$breaks)]
if (length(s) != length(obsp))
stop("problem when computing probabilities.")
plot(s, obsp, main = paste("Empirical and theoretical CDFs"),
xlab = "Data", ylab = "CDF", xlim = c(xmin,
xmax), ...)
sfin <- seq(xmin, xmax, by = (xmax - xmin)/100)
theopfin <- do.call(pdistname, c(list(sfin), as.list(para)))
lines(sfin, theopfin, lty = 1, col = "red")
theop <- do.call(pdistname, c(list(s), as.list(para)))
if (length(theop) != length(obsp))
stop("problem when computing probabilities.")
plot(theop, obsp, main = "P-P plot", xlab = "Theoretical probabilities",
ylab = "Empirical probabilities", ...)
abline(0, 1)
}
else {
par(mfrow = c(1, 2))
if (breaks != "default")
warning("Breaks are not taken into account for discrete distributions")
t <- table(data)
xval <- as.numeric(names(t))
xvalfin <- seq(min(xval), max(xval), by = 1)
xlinesdec <- min((max(xval) - min(xval))/30, 0.4)
yd <- do.call(ddistname, c(list(xvalfin), as.list(para)))
if (length(yd) != length(xvalfin))
stop("problem when computing density points.")
ydobs <- as.vector(t)/n
ydmax <- max(yd, ydobs)
plot(xvalfin + xlinesdec, yd, type = "h", xlim = c(min(xval),
max(xval) + xlinesdec), ylim = c(0, ydmax), lty = 1,
col = "red", main = "Emp. and theo. distr.",
xlab = "Data", ylab = "Density",
...)
points(xval, ydobs, type = "h", lty = 1, col = "black",
...)
legend("topright", lty = c(1, 1), col = c("black",
"red"), legend = c("empirical", paste("theoretical")),
bty = "o", bg = "white", cex = 0.6,
...)
ycdf <- do.call(pdistname, c(list(xvalfin), as.list(para)))
if (length(ycdf) != length(xvalfin))
stop("problem when computing probabilities.")
plot(xvalfin, ycdf, type = "s", xlim = c(min(xval),
max(xval) + xlinesdec), ylim = c(0, 1), lty = 1,
col = "red", main = "Emp. and theo. CDFs",
xlab = "Data", ylab = "CDF", ...)
ycdfobs <- cumsum(ydobs)
points(xval, ycdfobs, type = "p", col = "black",
...)
legend("bottomright", lty = c(1, 1), col = c("black",
"red"), legend = c("empirical", paste("theoretical")),
bty = "o", bg = "white", cex = 0.6,
...)
}
}
par(def.par)
invisible()
}
To now add a title to your plot, simply use this:
par(ask=F)
for (i in unique(Data$column_a)) {
dat <- Data[Data$column_a== i, ]
plotdist_alt(dat$count,histo = TRUE, demp = TRUE, discrete = T,
pch = 16, col = "dodgerblue1", title = i)
}
Edit: Added dummy data to test the provided loop.
df <- data.frame(column_a = rep(c("a", "b"), each = 50),
count = sample(1:1000, 100, replace = T))
par(ask=F)
for (i in unique(df$column_a)) {
dat <- df[df$column_a== i, ]
plotdist_alt(dat$count,histo = TRUE, demp = TRUE, discrete = T,
pch = 16, col = "dodgerblue1", title = i)
}
How do I change the size of the trace label, need to make it bigger. Is there any cex. function that I can use ?
This is my code
x <- interaction.plot(x.factor = data_flokvel$Vél.nr.,
trace.factor = data_flokvel$d ,
response = data_flokvel$Gallar..,
fun = mean, type = "b", fixed = TRUE,legend = TRUE,
col= c(1:6),lwd = 3, cex.lab= 1.5, cex.axis = 1.5,
cex.main = 1.5,lty = 1, ylab = "Flökunargallahlutfall (%)",
xlab = "Vél númer", trace.label = "Þyngd karfa í kg")
I am using Rstudio 0.99
and a reproducible example:
with(ToothGrowth, interaction.plot(dose, supp, len, fixed = TRUE) ))
I'm trying to recreate this plot that I made with the old (pre 0.10-0) version of xts. Here's some example data:
library(xts) # Run using xts_0.9-7
set.seed(190)
modelo_1 <- arima.sim(n = 252*8,list(ar = c(.99999),sd = sqrt(0.5)))
set.seed(256)
modelo_2 <- arima.sim(n = 252*8,list(ar = c(.9999),sd = sqrt(0.75)))
d1 <- as.Date("2008-01-01")
series_1 <- xts(modelo_1, seq(d1, by = "days", along.with = modelo_1))
series_2 <- xts(modelo_2, seq(d1, by = "days", along.with = modelo_2))
The code below uses the old version to create the graph I want.
par(mar = c(5, 4, 4, 4))
plot(series_1, las = 1, main = "", mar = c(5, 2, 2, 5))
par(new = TRUE)
plot(series_2, col = 2, axes = FALSE, main = "Two Series")
axis(4, las = 1)
lnames <- c("Series 1 (left)", "Series 2 (right)")
legend("top", legend = lnames, lty = 1, cex = 0.85, col = c(1, 2), bty = "n")
How can I create this plot with the new version of plot.xts()? Here's what I've tried, but both series use the same axis.
plot(cbind(series_1, series_2))
lnames <- c("Series 1", "Series 2")
addLegend("bottom", legend.names = lnames, ncol = 2, lty = 1, lwd = 1, cex = 1)
The old way of doing this is not working anymore, because of this issue.
plot(series_1, las = 1, yaxis.right = FALSE,yaxis.same = FALSE)
par(new = TRUE)
plot(series_2, col = 2, bty = "n", xaxt = "n", yaxt = "n", xlab = "", ylab = "")
axis(4, las = 1)
lnames <- c("Series 1", "Series 2")
legend("topleft", legend = lnames, col = 1:2, lty = 1, cex = 0.85)
I don't speak English very well so forgive me.
Below is the code with the change so that it plots as it was before.
note that the only change was to put the index as x in the plot function. Same index for both plot() functions
library(xts) # Run using xts_0.9-7
set.seed(190)
modelo_1 <- arima.sim(n = 252*8,list(ar = c(.99999),sd = sqrt(0.5)))
set.seed(256)
modelo_2 <- arima.sim(n = 252*8,list(ar = c(.9999),sd = sqrt(0.75)))
d1 <- as.Date("2008-01-01")
series_1 <- xts(modelo_1, seq(d1, by = "days", along.with = modelo_1))
series_2 <- xts(modelo_2, seq(d1, by = "days", along.with = modelo_2))
#O código abaixo usa a versão antiga para criar o gráfico que eu quero.
plot.new()
par(mar = c(5, 4, 4, 4))
plot(index(series_1),series_1, las = 1, main = "",
type = 'l', mar = c(5, 2, 2, 5))
par(new = TRUE)
plot(index(series_1),series_2, col = 2, axes = FALSE,
type = 'l', main = "Two Series")
axis(4, las = 1)
lnames <- c("Series 1 (left)", "Series 2 (right)")
legend("top", legend = lnames, lty = 1, cex = 0.85, col = c(1, 2), bty = "n")
I need to remove the lower control limit and center line (and their labels) from my control chart.
Here's the code:
# install.packages('qcc')
library(qcc)
nonconforming <- c(3, 4, 6, 5, 2, 8, 9, 4, 2, 6, 4, 8, 0, 7, 20, 6, 1, 5, 7)
samplesize <- rep(50, 19)
control <- qcc(nonconforming, type = "p", samplesize, plot = "FALSE")
warn.limits <- limits.p(control$center, control$std.dev, control$sizes, 2)
par(mar = c(5, 3, 1, 3), bg = "blue")
plot(control, restore.par = FALSE, title = "P Chart for Medical Insurance Claims",
xlab = "Day", ylab = "Proportion Defective")
abline(h = warn.limits, lty = 3, col = "blue")
v2 <- c("LWL", "UWL") # the labels for warn.limits
mtext(side = 4, text = v2, at = warn.limits, col = "blue", las = 2)
This approach seems more like a "hack" than an answer and it throws a warning:
control$center <- NULL
control$limits <- NULL
plot(control, add.stats = FALSE)
Not a QC expert by any means but would this work for you? Looking at the qcc function it seems to control what needs to be plotted, so what i've done here is manipulate the limits of the LCL and CENTRE lines. I then changed the plot function to plot between some y limits which does not cover the -1 value. The description unfortunately reflects the manipulated limit values of -1.
control$limits[1] <- -1
control$center <- -1
plot(control, restore.par = FALSE, title = "P Chart for Medical Insurance Claims",
xlab = "Day", ylab = "Proportion Defective", ylim=c(0.0,0.4))
The following function will do the required chart, and you don't need to change your control object, neither to know the control's limits. Load the function, then just call:
plot.qcc2(control, restore.par = FALSE, title = "P Chart for Medical Insurance Claims", + xlab = "Day", ylab = "Proportion Defective")
Function:
#Function plotting only UCL:
plot.qcc2 <- function (x, add.stats = TRUE, chart.all = TRUE, label.limits = c( "UCL"), title, xlab, ylab, ylim, axes.las = 0, digits = getOption("digits"),
restore.par = TRUE, ...)
{
object <- x
if ((missing(object)) | (!inherits(object, "qcc")))
stop("an object of class `qcc' is required")
type <- object$type
std.dev <- object$std.dev
data.name <- object$data.name
center <- object$center
stats <- object$statistics
limits <- object$limits
lcl <- limits[, 1]
ucl <- limits[, 2]
newstats <- object$newstats
newdata.name <- object$newdata.name
violations <- object$violations
if (chart.all) {
statistics <- c(stats, newstats)
indices <- 1:length(statistics)
}
else {
if (is.null(newstats)) {
statistics <- stats
indices <- 1:length(statistics)
}
else {
statistics <- newstats
indices <- seq(length(stats) + 1, length(stats) +
length(newstats))
}
}
if (missing(title)) {
if (is.null(newstats))
main.title <- paste(type, "Chart\nfor", data.name)
else if (chart.all)
main.title <- paste(type, "Chart\nfor", data.name,
"and", newdata.name)
else main.title <- paste(type, "Chart\nfor", newdata.name)
}
else main.title <- paste(title)
oldpar <- par(bg = qcc.options("bg.margin"), cex = qcc.options("cex"),
mar = if (add.stats)
pmax(par("mar"), c(8.5, 0, 0, 0))
else par("mar"), no.readonly = TRUE)
if (restore.par)
on.exit(par(oldpar))
plot(indices, statistics, type = "n", ylim = if (!missing(ylim))
ylim
else range(statistics, limits, center), ylab = if (missing(ylab))
"Group summary statistics"
else ylab, xlab = if (missing(xlab))
"Group"
else xlab, axes = FALSE, main = main.title)
rect(par("usr")[1], par("usr")[3], par("usr")[2], par("usr")[4],
col = qcc.options("bg.figure"))
axis(1, at = indices, las = axes.las, labels = if (is.null(names(statistics)))
as.character(indices)
else names(statistics))
axis(2, las = axes.las)
box()
lines(indices, statistics, type = "b", pch = 20)
if (length(center) == 1)
alpha <- 1
else lines(indices, c(center, center[length(center)]), type = "s")
if (length(lcl) == 1) {
abline(h = ucl, lty = 2)
}
else {
lines(indices, ucl[indices], type = "s", lty = 2)
}
mtext(label.limits, side = 4, at = c(rev(ucl)[1],rev(ucl)[1]),
las = 1, line = 0.1, col = gray(0.3))
if (is.null(qcc.options("violating.runs")))
stop(".qcc.options$violating.runs undefined. See help(qcc.options).")
if (length(violations$violating.runs)) {
v <- violations$violating.runs
if (!chart.all & !is.null(newstats)) {
v <- v - length(stats)
v <- v[v > 0]
}
points(indices[v], statistics[v], col = qcc.options("violating.runs")$col,
pch = qcc.options("violating.runs")$pch)
}
if (is.null(qcc.options("beyond.limits")))
stop(".qcc.options$beyond.limits undefined. See help(qcc.options).")
if (length(violations$beyond.limits)) {
v <- violations$beyond.limits
if (!chart.all & !is.null(newstats)) {
v <- v - length(stats)
v <- v[v > 0]
}
points(indices[v], statistics[v], col = qcc.options("beyond.limits")$col,
pch = qcc.options("beyond.limits")$pch)
}
if (chart.all & (!is.null(newstats))) {
len.obj.stats <- length(object$statistics)
len.new.stats <- length(statistics) - len.obj.stats
abline(v = len.obj.stats + 0.5, lty = 3)
mtext(paste("Calibration data in", data.name), at = len.obj.stats/2,
adj = 0.5, cex = 0.8)
mtext(paste("New data in", object$newdata.name), at = len.obj.stats +
len.new.stats/2, adj = 0.5, cex = 0.8)
}
if (add.stats) {
plt <- par()$plt
usr <- par()$usr
px <- diff(usr[1:2])/diff(plt[1:2])
xfig <- c(usr[1] - px * plt[1], usr[2] + px * (1 - plt[2]))
at.col <- xfig[1] + diff(xfig[1:2]) * c(0.1, 0.4, 0.65)
mtext(paste("Number of groups = ", length(statistics),
sep = ""), side = 1, line = 5, adj = 0, at = at.col[1],
font = qcc.options("font.stats"), cex = qcc.options("cex.stats"))
center <- object$center
if (length(center) == 1) {
mtext(paste("Center = ", signif(center[1], digits),
sep = ""), side = 1, line = 6, adj = 0, at = at.col[1],
font = qcc.options("font.stats"), cex = qcc.options("cex.stats"))
}
else {
mtext("Center is variable", side = 1, line = 6, adj = 0,
at = at.col[1], qcc.options("font.stats"), cex = qcc.options("cex.stats"))
}
mtext(paste("StdDev = ", signif(std.dev, digits), sep = ""),
side = 1, line = 7, adj = 0, at = at.col[1], font = qcc.options("font.stats"),
cex = qcc.options("cex.stats"))
if (length(unique(lcl)) == 1)
alpha <- 0
#mtext(paste("LCL = ", signif(lcl[1], digits), sep = ""),
# side = 1, line = 6, adj = 0, at = at.col[2],
# font = qcc.options("font.stats"), cex = qcc.options("cex.stats"))
else mtext("LCL is variable", side = 1, line = 6, adj = 0,
at = at.col[2], font = qcc.options("font.stats"),
cex = qcc.options("cex.stats"))
if (length(unique(ucl)) == 1)
mtext(paste("UCL = ", signif(ucl[1], digits), sep = ""),
side = 1, line = 7, adj = 0, at = at.col[2],
font = qcc.options("font.stats"), cex = qcc.options("cex.stats"))
else mtext("UCL is variable", side = 1, line = 7, adj = 0,
at = at.col[2], font = qcc.options("font.stats"),
cex = qcc.options("cex.stats"))
if (!is.null(violations)) {
mtext(paste("Number beyond limits =", length(unique(violations$beyond.limits))),
side = 1, line = 6, adj = 0, at = at.col[3],
font = qcc.options("font.stats"), cex = qcc.options("cex.stats"))
mtext(paste("Number violating runs =", length(unique(violations$violating.runs))),
side = 1, line = 7, adj = 0, at = at.col[3],
font = qcc.options("font.stats"), cex = qcc.options("cex.stats"))
}
}
invisible()
}
I want to plot 4 of the following plots as an par(mfrow=c(2,2)) type arrangement.
install.packages("wavelets")
require(wavelets)
dat <- rnorm(100)
plot.modwt(modwt(dat)) #4 of these in a 2x2 grid is desired
However, layout and mfrow based attempts have not succeeded.
I will be giving the correct answer a bounty.
As #plannapus commented, the function plot.modwt already calls layout. So you will need to alter the original function.
If you type plot.modwt in you R console, you will get the complete definition.
Copy this function and save it as a new function, say, my.plot.modwt.
Comment out the layout line in this function
Set up your new layout. This worked for me:
nf = layout(matrix(c(3, 1, 4, 2, 7, 5,8, 6), 4, 2, byrow = TRUE),
c(2,2), c(2,1, 2, 1), TRUE)
layout.show(nf)
Call your function (4 times )to create plots:
my.plot.modwt(modwt(dat1))
my.plot.modwt(modwt(dat2))
my.plot.modwt(modwt(dat3))
my.plot.modwt(modwt(dat4))
Note, some other alterations to the layout will probably be needed.
My code:
y.plot.modwt = function (x, levels = NULL, draw.boundary = FALSE, type = "stack",
col.plot = "black", col.boundary = "red", X.xtick.at = NULL,
X.ytick.at = NULL, Stack.xtick.at = NULL, Stack.ytick.at = NULL,
X.xlab = "t", y.rlabs = TRUE, plot.X = TRUE, plot.W = TRUE,
plot.V = TRUE, ...)
{
stackplot.modwt <- function(x, w.range, v.range, col.plot,
col.boundary, draw.boundary, X.xtick.at, X.ytick.at,
Stack.xtick.at, Stack.ytick.at, X.xlab = "t", plot.X = TRUE) {
innerplot <- function(x, y, type = "l", xtick.at, ytick.at) {
if (is.null(xtick.at) == FALSE || is.null(ytick.at) ==
FALSE) {
plot(x, y, type = "l", axes = FALSE, frame.plot = TRUE)
<snip>
if (plot.X) {
#nf <- layout(matrix(c(2, 2, 1, 1), 2, 2, byrow = TRUE),
# c(1, 2), c(2, 1), TRUE)
par(mai = c(0.6, 0.4, 0.1, 0.6))
<snip>
}