Change of col argument throwing an error and how to store individual graphical parameters - r

I'll try to define my companies colors and fonts etc to all the plots we're doing. So first question: How can I store them without overwriting the "normal" par settings? I mean can I store all in a "par-Container" and give them to each plot etc?
Ok here I defined the Colors:
GRAPH_BLUE<-rgb(43/255, 71/255,153/255)
GRAPH_ORANGE<-rgb(243/255, 112/255, 33/255)
GRAPH_BACKGROUND<-rgb(180/255, 226/255, 244/255)
If I do plot(something, col=GRAPH_BLUE) I get the error:
Error in axis(1, at = xycoords$x, labels = FALSE, col = "#BBBBBB", ...) :
formal argument "col" matched by multiple actual arguments
If I do par(col=GRAPH_BLUE) and plot(something) it works exactly as I want. Why is that? What would I need to change that it works in the first line of code? As I understand it throws the error since there are multiple settings starting with col and with plot(something, col=GRAPH_BLUE) I overwrite all of them and that's why the axis isn't visible. But is there a special col setting for just the color line of the chart?
EDIT: Ok here's a reproducible example:
getSymbols('SPY', from='1998-01-01', to='2011-07-31', adjust=T)
GRAPH_BLUE<-rgb(43/255, 71/255,153/255)
GRAPH_ORANGE<-rgb(243/255, 112/255, 33/255)
GRAPH_BACKGROUND<-rgb(180/255, 226/255, 244/255)
par(col=GRAPH_BLUE)
plot.xts(SPY) #works great
plot.xts(SPY, col=GRAPH_ORANGE) #not really since all axes are missing
And the first question is if I could store all these Settings not directly in par() but in another variable which I pass to the plot function?

No there isn't a special col setting for just the color line of the chart. You should use par or modify the code source of the function and add it like the case of bar.col or candle.col. I don't know why they do it for types bar and candle and not for lines? I guess to not have a lot of parameters...
Note the you can save the old parameters of par every time you change it.
op <- par(col=GRAPH_BLUE)
... ## some plot job
par(op) ## retsore it
It easy also to hack the function and add a new col parameters for lines. Only few lines to change in the function:
plot.xts.col <- function (old.parameters,lines.col='green', ...) {
.....
## you change this line to add the paremeter explicitly
plot(xycoords$x, xycoords$y, type = type, axes = FALSE,
ann = FALSE,col=lines.col, ...)
## and the last line since .xtsEnv is an internal object
assign(".plot.xts", recordPlot(), xts:::.xtsEnv)
}

Related

Is there a way to force a parameter to be passed through as a dot-dot-dot parameter?

I have a function that I would like to call with a certain parameter as one of the dot-dot-dot paramets (col) unfortunately this function already has three named variables starting with col (colNonSig, colSig, and colLine) and so preferentially matches these:
As the documentation above mentions, I would like to pass through col to the underlying call to plot.
The body of the function plotMA can be found here and in its second last line includes a call to base R plot that looks like this:
plot(object$mean, pmax(ylim[1], pmin(ylim[2], py)),
log = log, pch = ifelse(py < ylim[1], 6, ifelse(py > ylim[2], 2, 16)),
cex = cex, col = ifelse(object$sig, colSig, colNonSig), xlab = xlab,
ylab = ylab, ylim = ylim, ...)
You can see that internally, plotMA already uses the col parameter, by taking the colNonSig and colSig variables and using them to determine what color the points will be based on their significance level. This is why you get the error about matching multiple arguments. It is not that you are partially matching arguments with plotMA, but that you are passing two col arguments to base R's plot inside the plotMA function.
There is no direct way round this that will allow you to pass col directly to the function, but since you want to pass a vector of colors instead, you should get the same result by passing the vector of colors you wanted to pass to both colSig and colNonSig, since this will result in a copy of that vector being passed to col internally.
Your other option is to create your own copy of the function which just removes the col = ifelse(object$sig, colSig, colNonSig), in the above code, but that seems a bit pointless when the work-around is so easy.

How do I change line thickness in denscomp plots from the fitdistrplus package in R?

I'm over-plotting three densities onto my data histogram, using denscomp in the fitdistrplus package in R. The code below is working perfectly, but I don't know how to make the lines thicker.
denscomp(list(TryWeibull, TryGamma, TryLognormal), legendtext = plot.legend,
fitcol = c("indianred3","gray38", "darkblue"), fitlty = c("dashed", "longdash", "dotdash"),
xlab = "Age", ylab = "Proportion", main="")
fitcol is giving me the correct colours, fitly is giving me the correct line types, but I can't work out the command to make the lines thicker. I have two distribution densities that are close together and I have been unsuccessful in clearly identifying them using colour/line type differences. .
I am trying to de-emphasize the Weibull and emphasise the gamma and lognormal. The proportions are estimates, so I am trying to fit the general shape, not the exact values.
I can't see an option in the denscomp function to specify line widths. I would rather not use the ggplot option, but can shift to that if required. I was hoping there was a function option I'm overlooking.
Edited to add: I raised this as a feature request on GitHub and it has been implemented into the package.
Although the author of this package allows you to specify multiple line types (fitlty) and line colours (fitcol), they didn't allow you to specify multiple line widths. But since R is open-source, you are free to modify the function in any way.
Type the following at the R console:
fix(denscomp)
Then add a new argument to the function after fitcol, called fitlwd.
..., fitcol, fitlwd, addlegend = TRUE, ...
Then after line 30 add the following:
if (missing(fitlwd))
fitlwd <- 1
Then after line 34 add the following:
fitlwd <- rep(fitlwd, length.out = nft)
Then modify line 136 as follows:
col = fitcol[i], lwd=fitlwd[i], ...)
Finally, modify line 142:
col = fitcol, lwd=fitlwd,
Save and call the new function as before but now specifying the fitlwd argument:
denscomp(..., fitlwd=c(1,3,3))
I had the same question and followed Edward's solution, which was great and I learnt a lot, but it turned out you can just use ggplot to do that.
denscomp(..., plotstyle = "ggplot") + geom_line(linetype = "dashed",size = 1))

Controlling addLines

I have an xts object (NCGSpot) I use for charting and would like to add a vertical line on a given date to the plot. Here is what I do:
chartSeries(NCGSpot, TA="addBBands();addLines()", subset="2015-04-02::2016-08-01",theme="white")
How can I control where the Lines is drawn. I have seen stuff like
addLines(v=anynumber)
But I cannot make much sense out of it and could not find any information on it.
Its there any way I pass on a date to addLines and get the line on that date?
Thx in advance
If you use chart_Series, (better charting capabilities than chartSeries) you can create vertical lines from scratch using an xts object containing a matrix type of logical, where TRUE applies to the dates where vertical lines are desired. The argument on should be set to 1 or -1 if you want the vertical lines on your main chart. Setting -1 will put the lines behind the candles. Other useful parameters included col and border (should be self explanatory). Here is an example to get you started:
library(quantmod)
getSymbols("AAPL")
xt <- xts(rep(FALSE, NROW(AAPL)), index(AAPL))
dates_for_vertical_marks <- c("2016-02-01", "2016-04-29")
xt[dates_for_vertical_marks, ] <- TRUE
xt2 <- xts(rep(FALSE, NROW(AAPL)), index(AAPL))
dates_for_vertical_marks <- c("2016-07-01")
xt2[dates_for_vertical_marks, ] <- TRUE
chart_Series(AAPL, subset="2016")
add_TA(xt, on =-1, col= "orange", border='blue')
add_TA(xt2, on = 1, col= "darkgreen", border='darkgreen')

Change of colors in compare.matrix command in r

I'm trying to change the colors for the compare.matrix command in r, but the error is always the same:
Error in image.default(x = mids, y = mids, z = mdata, col = c(heat.colors(10)[10:1]), :
formal argument "col" matched by multiple actual arguments
My code is very simple:
compare.matrix(current,ech_b1,nbins=40)
and some of my attempts are:
compare.matrix(current,ech_b1,nbins=40,col=c(grey.colors(5)))
compare.matrix(current,ech_b1,nbins=40,col=c(grey.colors(10)[10:1]))
Assuming you're using compare.matrix() from the SDMTools package, the color arguments appear to be hard-coded into the function, so you'll need to redefine the function in order to make them flexible:
# this shows you the code in the console
SDMTools::compare.matrix
function(x,y,nbins,...){
#---- preceding code snipped ----#
suppressWarnings(image(x=mids, y=mids, z=mdata, col=c(heat.colors(10)[10:1]),...))
#overlay contours
contour(x=mids, y=mids, z=mdata, col="black", lty="solid", add=TRUE,...)
}
So you can make a new one like so, but bummer, there are two functions using the ellipsis that have a col argument predefined. If you'll only be using extra args to image() and not to contour(), this is cheap and easy.
my.compare.matrix <- function(x,y,nbins,...){
#---- preceding code snipped ----#
suppressWarnings(image(x=mids, y=mids, z=mdata,...))
#overlay contours
contour(x=mids, y=mids, z=mdata, col="black", lty="solid", add=TRUE)
}
If, however, you want to use ... for both internal calls, then the only way I know of to avoid confusion about redundant argument names is to do something like:
my.compare.matrix <- function(x,y,nbins,
image.args = list(col=c(heat.colors(10)[10:1])),
contour.args = list(col="black", lty="solid")){
#---- preceding code snipped ----#
contour.args[[x]] <- contour.args[[y]] <- image.args[[x]] <- image.args[[y]] <- mids
contour.args[[z]] <- image.args[[z]] <- mdata
suppressWarnings(do.call(image, image.args))
#overlay contours
do.call(contour, contour.args)
}
Decomposing this change: instead of ... make a named list of arguments, where the previous hard codes are now defaults. You can then change these items by renaming them in the list or adding to the list. This could be more elegant on the user side, but it gets the job done. Both of the above modifications are untested, but should get you there, and this is all prefaced by my above comment. There may be some other problem that cannot be detected by SO Samaritans because you didn't specify the package or the data.

error labelling axis of plot using Ecdf

I am attempting to plot a graph using the code below:
Require(Hmisc)
Ecdf(ceac_primary,xlab="axis label",xlim=c(5000,50000),q=c(0.9,0.1),
ylab="Probability of Success",main="CEAC")
Where ceac_primary is a data frame with 1 variable of 90k observations.
When I include the 'xlab="axis label"' I keep getting the following error:
Error in Ecdf.default(v, group = group, weights = weights, normwt = normwt, :
formal argument "xlab" matched by multiple actual arguments
However if I exclude the x axis label part of the code, it plots the graph fine.
Is this a known problem, and if so, are there alternative ways to plot an x axis label?
Thanks
Digging around in the source code for Ecdf.data.frame (the method that is called when passing a data.frame to Ecdf), it looks like that function creates an object that is later passed to the xlab argument. Therefore, xlab is not expected as a user-supplied argument when running Ecdf with a data.frame. Here's the code that creates the object lab that gets passed to xlab within Ecdf.data.frame:
lab <- if (vnames == "names")
nam[j]
else label(v, units = TRUE, plot = TRUE, default = nam[j])
Then Ecdf is called with xlab = lab, but also any arguments in the elipses of Ecdf.data.frame are also passed to Ecdf. Since xlab is not a formal argument of Ecdf.data.frame, this is why you get your error.
To get around it, try either of the following:
Convert your data.frame to a vector of the appropriate class (numeric, I presume), and then run
Ecdf(ceac_primary_Vec, xlab = "axis label")
Or, you can create a label for the one column in your data.frame using the label function in the Hmisc package. If that column is called myCol, you can run
label(ceac_primary$myCol) <- "axis label"
Ecdf(ceac_primary)
And that should get your axis label printing correctly.

Resources