How do I change line thickness in denscomp plots from the fitdistrplus package in R? - 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))

Related

plot function in R producing legend without legend() being called

I'm trying to produce a cumulative incidence plot for a competing hazards survival analysis using plot() in R. For some reason, the plot that is produced has a legend that I have not called. The legend is intersecting with the lines on my graph and I can't figure out how to get rid of it. Please help!
My code is as follows:
CompRisk2 <- cuminc(ftime=ADI$time_DeathTxCensor, fstatus=ADI$status, group=ADI$natADI_quart)
cols <- c("darkorange","coral1","firebrick1","firebrick4","lightskyblue","darkturquoise","dodgerblue","dodgerblue4")
par(bg="white")
plot(CompRisk2,
col=cols,
xlab="Years",
ylab="Probability of Mortality or Transplant",
xlim=c(0,10),
ylim=c(0,0.6))
Which produces the following plot:
I tried adding the following code to move the legend out of the frame, but I got an error:
legend(0,5, legend=c(11,21,31,41,12,22,32,42),
col=c("darkorange","coral1","firebrick1","firebrick4","lightskyblue","darkturquoise","dodgerblue","dodgerblue4"),
lty=1:2, cex=0.8, text.font=4, box.lty=0)
Error: Error in title(...) : invalid graphics parameter
Any help would be much appreciated!
You are using the cuminc function from the cmprsk package. This produces an object of class cuminc, which has an S3 plot method. ?plot.cuminc shows you the documentation and typing plot.cuminc shows you the code.
There is some slightly obscure code that suggests a workaround:
u <- list(...)
if (length(u) > 0) {
i <- pmatch(names(u), names(formals(legend)), 0)
do.call("legend", c(list(x = wh[1], y = wh[2], legend = curvlab,
col = color, lty = lty, lwd = lwd, bty = "n", bg = -999999),
u[i > 0]))
}
This says that any additional arguments passed in ... whose names match the names of arguments to legend will be passed to legend(). legend() has a plot argument:
plot: logical. If ‘FALSE’, nothing is plotted but the sizes are returned.
So it looks like adding plot=FALSE to your plot() command will work.
In principle you could try looking at the other arguments to legend() and see if any of them will adjust the legend position/size as you want. Unfortunately the x argument to legend (which would determine the horizontal position) is masked by the first argument to plot.cuminc.
I don't think that the ellipsis arguments are intended for the legend call inside plot.cuminc. The code offered in Ben's answer suggests that there might be a wh argument that determines the location of the legend. It is not named within the parameters as "x" in the code he offered, but is rather given as a positionally-defined argument. If you look at the plot.cuminc function you do in fact find that wh is documented.
I cannot test this because you have not offered us access to the ADI-object but my suggestion would be to try:
opar <- par(xpd=TRUE) # xpd lets graphics be placed 'outside'
plot(CompRisk2,
col=cols, wh=c(-.5, 7),
xlab="Years",
ylab="Probability of Mortality or Transplant",
xlim=c(0,10),
ylim=c(0,0.6))
par(opar) # restores original graphics parameters
It's always a bit risky to put out a code chunk without testing, but I'm happy to report that I did find a suitable test and it seems to work reasonably as predicted. Using the code below on the object in the SO question prior question about using the gg-packages for cmprsk:
library(cmprsk)
# some simulated data to get started
comp.risk.data <- data.frame("tfs.days" = rweibull(n = 100, shape = 1, scale = 1)*100,
"status.tfs" = c(sample(c(0,1,1,1,1,2), size=50, replace=T)),
"Typing" = sample(c("A","B","C","D"), size=50, replace=T))
# fitting a competing risks model
CR <- cuminc(ftime = comp.risk.data$tfs.days,
fstatus = comp.risk.data$status.tfs,
cencode = 0,
group = comp.risk.data$Typing)
opar <- par(xpd=TRUE) # xpd lets graphics be placed 'outside'
plot(CR,
wh=c(-15, 1.1), # obviously different than the OP's coordinates
xlab="Years",
ylab="Probability of Mortality or Transplant",
xlim=c(0,400),
ylim=c(0,1))
par(opar) # restores graphics parameters
I get the legend to move up and leftward from its original position.

Is there a way to remove points from a Mclust classification plot in R?

I am trying to plot the GMM of my dataset using the Mclust package in R. While the plotting is a success, I do not want points to show in the final plot, just the ellipses. For a reference, here is the plot I have obtained:
GMM Plot
But, I want the resulting plot to have only the ellipses, something like this:
GMM desired plot
I have been looking at the Mclust plot page in: https://rdrr.io/cran/mclust/man/plot.Mclust.html and looking at the arguments of the function, I see there is a scope of adding other graphical parameters. Looking at the documentation of the plot function, there is a parameter called type = 'n' which might help to do what I want but when I write it, it produces the following error:
Error in plot.default(data[, 1], data[, 2], type = "n", xlab = xlab, ylab = ylab, :
formal argument "type" matched by multiple actual arguments
For reference, this is the code I used for the first plot:
library(mclust)
Data1_2 <- Mclust(Data, G=15)
summary(Data1_2, parameters = TRUE, classification = TRUE)
plot(Data1_2, what="classification")
The code I tried using for getting the graph below is:
Data1_4 <- Mclust(Data, G=8)
summary(Data1_4, parameters = TRUE, classification = TRUE)
plot(Data1_4, what="classification", type = "n")
Any help on this matter will be appreciated. Thanks!
If you look under the source code of plot.Mclust, it calls plot.Mclust.classification which in turn calls coordProj for the dot and ellipse plot. Inside this function, the size is controlled by the option CEX= and shape PCH=.
So for your purpose, do:
library(mclust)
clu = Mclust(iris[,1:4], G = 3, what="classification")
plot(clu,what="classification",CEX=0)

Can't change axes in R for density plots when using mixtools

This should be easy to fix, I genuinely don't know what is wrong.
Suppose I wanted to perform the EM algorithm for the Old Faithful data in R and plot the results:
install.packages('mixtools')
library('mixtools')
test<-normalmixEM(faithful$waiting, k=2)
plot(test, which=2, xlim= c(30, 100))
lines(density(faithful$waiting), lty=2, lwd=2)
This works.
But if I wanted to change the x-label or y-axis I get an error message:
plot(test, which=2, xlim= c(30, 100), xlab="", ylim= c(0, 0.06))
lines(density(faithful$waiting), lty=2, lwd=2)
The message is:
argument 4 matches multiple formal arguments
Can someone please help me out? What am I doing wrong? I'm really puzzled.
Thanks!
From the documentation you need to follow this form:
plot(x, whichplots = 1,
loglik = 1 %in% whichplots,
density = 2 %in% whichplots,
xlab1="Iteration", ylab1="Log-Likelihood",
main1="Observed Data Log-Likelihood", col1=1, lwd1=2,
xlab2=NULL, ylab2=NULL, main2=NULL, col2=NULL,
lwd2=2, alpha = 0.05, marginal = FALSE, ...)
you'll need to use xlab2 = ...
plot() is a generic function that actually calls a more specific function (called a "method") depending on what you are trying to plot (see this chapter from Hadley Wickham's Advanced R book for details). In this case, you are feeding-in an object of class "mixEM" to plot(). You can see this by running, e.g.:
class(test)
The generic function plot() is calling the method plot.mixEM() because you are feeding in an object of type "mixEM". To see which parameters of plot.mixEM() you can control, check out that function's help page
?plot.mixEM
The helpfile makes it clear that you need xlab2 as an argument instead of xlab. However, I don't immediately see how to change ylim, so you should view the source code for plot.mixEM to see if there's a way to adjust it other components of the graph:
getAnywhere(plot.mixEM)

How do I exclude parameters from an RDA plot

I'm still relatively inexperienced manipulating plots in R, and am in need of assistance. I ran a redundancy analysis in R using the rda() function, but now I need to simplify the figure to exclude unnecessary information. The code I'm currently using is:
abio1516<-read.csv("1516 descriptors.csv")
attach(abio1516)
bio1516<-read.csv("1516habund.csv")
attach(bio1516)
rda1516<-rda(bio1516[,2:18],abio1516[,2:6])
anova(rda1516)
RsquareAdj(rda1516)
summary(rda1516)
varpart(bio1516[,2:18],~Distance_to_source,~Depth, ~Veg._cover, ~Surface_area,data=abio1516)
plot(rda1516,bty="n",xaxt="n",yaxt="n",main="1516; P=, R^2=",
ylab="Driven by , Var explained=",xlab="Driven by , Var explained=")
The produced plot looks like this:
Please help me modify my code to: exclude the sites (sit#), all axes, and the internal dashed lines.
I'd also like to either expand the size of the field, or move the vector labels to all fit in the plotting field.
updated as per responses, working code below this point
plot(rda,bty="n",xaxt="n",yaxt="n",type="n",main="xxx",ylab="xxx",xlab="xxx
Overall best:xxx")
abline(h=0,v=0,col="white",lwd=3)
points(rda,display="species",col="blue")
points(rda,display="cn",col="black")
text(rda,display="cn",col="black")
Start by plotting the rda with type = "n" which generates an empty plot to which you can add the things you want. The dotted lines are hard coded into the plot.cca function, so you need either make your own version, or use abline to hide them (then use box to cover up the holes in the axes).
require(vegan)
data(dune, dune.env)
rda1516 <- rda(dune~., data = dune.env)
plot(rda1516, type = "n")
abline(h = 0, v = 0, col = "white", lwd = 3)
box()
points(rda1516, display = "species")
points(rda1516, display = "cn", col = "blue")
text(rda1516, display = "cn", col = "blue")
If the text labels are not in the correct position, you can use the argument pos to move them (make a vector as long as the number of arrows you have with the integers 1 - 4 to move the label down, left, up, or right. (there might be better solutions to this)

Color option in xtsExtra

I am having trouble adjusting the colors of a multiple time series plot using xtsExtra.
This is the code of a minimal example:
require("xtsExtra")
n <- 50
data <- replicate(2, rnorm(n))
my.ts <- as.xts(ts(data, start=Sys.Date()-n, end=Sys.Date()))
plot.zoo(my.ts, col = c('blue', 'green'))
plot.xts(my.ts, col = c('blue', 'green'))
The plot.zoo commands yields
,
whereas the plot command from the xtsExtra package results in
.
In the second plot, the two time series are nicely overlaid, but seem insensitive to the col option.
I'm using the latest version 0.0-1 of the xtsExtra package (rev. 862).
It is my understanding that the xts and xtsExtra packages are designed as extensions of zoo and should work with the same arguments (plus many additional ones). Even though I can get the same overlay behavior in plot.zoo using the screens option, I cannot really resort to using it because the call to plot.xts that causes my problems is within the quantstrat package (functions chart.forward.training and chart.forward.testing for example) which I'd loathe to modify. (Incidentally, the dev.new() in these functions is causing me trouble as well.)
Question: Why does plot from the xtsExtra package seem not to respond to the col= option and what can be done about it, if modifying
the call to the function is not a real option?
Q1. If you take time to read the help text for plot.xts, you see that the function does not have a col argument. Together with the fact that partial matching of argument names doesn't seem to be allowed in the function, it explains why plot.xts it does not respond col =.
Compare with a case where partial matching works:
plot(x = 1:2, y = 1:2, type = "b"); plot(x = 1:2, y = 1:2, ty = "b"); "ty" matches "type".
See here: "If the name of the supplied argument matches exactly with the first part of a formal argument then the two arguments are considered to be matched".
Q2. Instead you may use the colorset argument:
"color palette to use, set by default to rational choices" (colorset = 1:12).
plot.xts(my.ts, colorset = c('blue', 'green'))

Resources