I have a plot in R that I am trying to replicate in ggplot2. I have the following code:
theta = seq(0,1,length=500)
post <- dgamma(theta,0.5, 1)
plot(theta, post, type = "l", xlab = expression(theta), ylab="density", lty=1, lwd=3)
I have tried to replicate this plot in ggplot2 and this is the closest I was able to get.
df=data_frame(post,theta)
ggplot(data=df,aes(x=theta))+
stat_function(fun=dgamma, args=list(shape=1, scale=.5))
You didn't match up your parameters correctly. The signature of dgamma is
dgamma(x, shape, rate = 1, scale = 1/rate, log = FALSE)
so when you call
dgamma(theta, 0.5, 1)
that's
dgamma(theta, shape=0.5, rate=1)
which means you would translate the ggplot as
ggplot(data=df,aes(x=theta))+
stat_function(fun=dgamma, args=list(shape=0.5, rate=1))
you could also adjust the y-limits if you like with scale_y_continuous(limits=c(0,12)) or something similar.
Related
I am trying to plot an NMDS plot of species community composition data with ellipses which represent 95% confidence intervals. I generated the data for my NMDS plot using metaMDS and successfully have ordinations generated using the basic plot functions in R (see code below). However, I am struggling to get my data to plot successfully using ggplot2 and this is the only way I have seen 95% CIs plotted on NMDS plots. I am hoping someone is able to help me correct my code so the ellipses show 95% CIs, or could point me in the right direction for achieving this using other methods?
My basic code for plotting my NMDS plot:
orditorp(dung.families.mds, display = "sites", labels = F, pch = c(16, 8, 17, 18) [as.numeric(group.variables$Heating)], col = c("green", "blue", "orange", "black") [as.numeric(group.variables$Dungfauna)], cex = 1.3)
ordiellipse(dung.families.mds, groups = group.variables$Dungfauna, draw = "polygon", lty = 1, col = "grey90")
legend("topleft", "stress = 0.1329627", bty = "n", cex = 1)
My ordination:
I realize this question is old, but I found this post useful for plotting confidence ellipses during my work, and maybe it will help you. Plotting ordiellipse function from vegan package onto NMDS plot created in ggplot2
Edit: Below I have copied the code from the second part of Didzis Elferts's answer on the link above.
Where "sol" is the metaMDS object:
First, make NMDS data frame with group column.
NMDS = data.frame(MDS1 = sol$points[,1], MDS2 = >sol$points[,2],group=MyMeta$amt)
Next, save result of function ordiellipse() as some object.
ord<-ordiellipse(sol, MyMeta$amt, display = "sites", >kind = "se", conf = 0.95, label = T)
Data frame df_ell contains values to show ellipses. It is calculated again with function veganCovEllipse which is hidden in vegan package. This function is applied to each level of NMDS (group) and now it uses arguments stored in ord object - cov, center and scale of each level.
df_ell <- data.frame()
for(g in levels(NMDS$group)){
df_ell <- rbind(df_ell, cbind(as.data.frame(with(NMDS[NMDS$group==g,],
veganCovEllipse(ord[[g]]$cov,ord[[g]]$center,ord[[g]]$scale)))
,group=g))
}
Plotting is done the same way as in previous example. As for the calculating of coordinates for elipses object of ordiellipse() is used, this solution will work with different parameters you provide for this function.
ggplot(data = NMDS, aes(MDS1, MDS2)) + geom_point(aes(color = group)) +
geom_path(data=df_ell, aes(x=NMDS1, y=NMDS2,colour=group), size=1, linetype=2)
I'm attempting to plot two locfit models within one plot however I am unable to get the second locfit model to plot the confidence intervals. I've created two locfit models:
1_fit = locfit(Y~Time,data=data_1)
2_fit = locfit(Y~Time,data=data_2)
Each can be plotted on their own just fine with the confidence intervals using the following:
plot(1_fit,band="local",type = "l", xlab = "Time", ylab = "Y-Axis",ylim=c(0,22),
col = "red",lwd = 5,font=3,main="Local Poly Fit 1",cex.lab=1.5, cex.axis=1.5,
cex.main=1.5, cex.sub=1.5)
However, when I attempt to plot an additional locfit model to the plot using:
lines(2_fit,col="blue")
I can only add the locfit line but not the confidence intervals. I've attempted to do:
lines(2_fit,band="local",col="blue")
But I get this message and no confidence intervals:
Warning message:
In plot.xy(xy.coords(x, y), type = type, ...) :
"band" is not a graphical parameter
I've also looked into using lines.locfit, but had no luck as R just says that it can't find the function lines.locfit.
I have a work around to put both plots within the same window using:
par(mfrow=c(2,1))
But would like to avoid this as it would make the plots more comparable if they were within the same plot.
Answer was provided by Richard Telford in comments. The following code was able to accomplish what I needed:
plot(1_fit,band="local",type = "l", xlab = "Time", ylab = "Y-Axis",ylim=c(0,22), xlim=c(0,12), col = "red",lwd = 5,font=3,main="Local Poly Fit 1",cex.lab=1.5, cex.axis=1.5, cex.main=1.5, cex.sub=1.5)`
par(new = TRUE)
plot(2_fit,band="local",type = "l", xlab = "Time", ylab = "Y-Axis",ylim=c(0,22), xlim=c(0,12),col = "blue",lwd = 5,font=3,main="Local Poly Fit 1",cex.lab=1.5, cex.axis=1.5, cex.main=1.5, cex.sub=1.5)`
I needed to be sure that ylim and xlim were equal as well as main, ylab, and xlab. Also a side note from Richard, 1_fit is not a legal name, I used it here just as a placeholder name but seems good knowledge to pass on.
I use following example code to plot an impulse response function:
# Load data and apply VAR
library("vars")
data(Canada)
data <- Canada
data <- data.frame(data[,1:2])
names(data)
var <- VAR(data, p=2, type = "both")
# Apply IRf
irf <- irf(var, impulse = "e", response = "prod", boot = T, cumulative = FALSE, n.ahead = 20)
str(irf)
plot(irf)
# Response
irf$irf
# Lower & Higher
irf$Lower
irf$Upper
#Create DataFrame and Plot
irf_df <- data.frame(irf$irf,irf$Lower,irf$Upper)
irf_df$T<-seq.int(nrow(irf_df)) #T
irf_df
plot(data.frame(irf_df$T, irf_df[1]), type="l", main="Impulse Response")
abline(h=0, col="blue", lty=2)
It looks like it works so far, though I sense that the code could be improved.
Would it be possible to add a confidence band for the Lower and Upper bounds of the confidence interval?
If you want to plot the Lower and Upper bands, you can use the lines() function, setting the y-limits of the plot if desired.
plot(irf_df$T, irf_df$prod, type="l", main="Impulse Response",
ylim = c(min(irf_df$prod.1), max(irf_df$prod.2)) * 1.1)
abline(h=0, col="blue", lty=2)
lines(irf_df$T, irf_df$prod.1, lty = 2)
lines(irf_df$T, irf_df$prod.2, lty = 2)
For a fancier plot with the confidence band filled in, use polygon. Here, we set up an empty plot, then plot the polygon, and finally overlay the line. Also note here that there's no need to set up a new data.frame: we can simply use values from the irf() output:
plot(irf$irf$e, type = "n", main = "Impulse Response",
ylim = c(min(irf$Lower$e), max(irf$Upper$e)))
polygon(x = c(seq_along(irf$irf$e), rev(seq_along(irf$irf$e))),
y = c(irf$Lower$e, rev(irf$Upper$e)),
lty = 0, col = "#fff7ec")
lines(irf$irf$e)
Output:
I use function fitdist in package fitdistrplus to get the best distribution fitted to my data and draw the ppcomp figure , I use the example codes of ?fitdistrplus to replace my data and codes.
data(groundbeef)
serving <- groundbeef$serving
fitW <- fitdist(serving, "weibull")
fitg <- fitdist(serving, "gamma")
fitln <- fitdist(serving, "lnorm")
ppcomp(list(fitW, fitg, fitln), legendtext=c("Weibull", "gamma", "lognormal"))
So far so good! But look at the left bottom of the pic, there is some space, or the axes does not start from zero!
So I googled and find two methods:
One method in the base plot, xaxs and yaxs are used.
set.seed(1234)
x <- runif(100, min=0, max=100)
y <- runif(100, min=0, max=100)
plot(x,y,xaxs="i",yaxs="i",xlim=c(0,100),ylim=c(0,100))
Another method in the ggplot2, expand=c(0,0) is used.
df <- data.frame(x=x,y=y)
ggplot(df,aes(x,y)) + geom_point() + scale_x_continuous(expand = c(0,0)) + scale_y_continuous(expand = c(0,0))
So I try to use these two methods to draw the ppcomp figure,
ppcomp(list(fitW, fitg, fitln), legendtext=c("Weibull", "gamma", "lognormal"),xaxs="i",yaxs="i")
but error occurs:
Error in legend(x = xlegend, y = ylegend, bty = "n", legend = legendtext, :
unused arguments (xaxs = "i", yaxs = "i")
So, what should I do to complete the goal without the error, or what is the right codes?
The problem seems to be that the ... argument in ppcomp (which accepts the extra arguments) is given to both plot and legend and legend does not know what to do with xaxs.
Options are:
1) Run ppcomp with xaxs, which will make the plot and then add the legend separately.
2) Use fix(ppcomp) to delete the ... from the legend commands.
3) Recode ppcomp to use ggplot and set the options as you please.
I have the following script:
FGM = function (n,r,z){
x = r*sqrt(n)/(2*z)
Px = 1-pnorm(x)
}
re = 10000
data = data.frame(abs(rnorm(re,0,1)), abs(rnorm(re,0,1)), abs(rnorm(re,0,1)))
colnames(data) = c("n","r","z")
data$Px = FGM(data$n,data$r,data$z)
data$x = data$r*sqrt(data$n)/(2*data$z)
par(mar=c(4.5,4.5,1,1))
plot(data$x,data$Px, xlim = c(0,3), pch = 19, cex = 0.1, xaxs="i", yaxs="i",
xlab = expression(paste("Standardized mutational size (",italic(x), ")")),
ylab = expression(paste("P"[a],"(",italic(x),")")))
Which is a recreation of the graph found here (box 2). You can see in this script that I do this by just plotting 10000 small black points with various values of n,z, and r. This seems like an ugly work around, I think I should just be able to give R my function
FGM = function (n,r,z){
x = r*sqrt(n)/(2*z)
Px = 1-pnorm(x)
}
and have it plot a line on a graph. However, a few hours of scouring the web has been unproductive, and I tried a few ways with abline and lines but nothing worked, is there a way of doing it with these functions or another function?
Tried this...
plot(data$x,data$Px, xlim = c(0,3), ylim = c(0,0.5), xaxs="i", yaxs="i",
xlab = expression(paste("Standardized mutational size (",italic(x), ")")),
ylab = expression(paste("P"[a],"(",italic(x),")")), type = "n")
curve(1-pnorm(r*sqrt(n)/(2*z)), add=T)
>Error in curve(1 - pnorm(r * sqrt(n)/(2 * z)), add = T) :
'expr' must be a function, or a call or an expression containing 'x'
>
#PaulRegular offered this solution but it still plots based on data, not the formula itself. I'm looking for a solution which can produce the curve properly without large values of "re" - using the following but with "re" set to 10 you can see what I mean...
data <- data[order(data$x),]
lines(data$x, data$Px, lwd=1)
You can pass a function of just one variable to plot. I guess that you are looking for:
plot(function(x) 1-pnorm(x),0,3)
Try sorting your data by x, then add the line:
data <- data[order(data$x),]
lines(data$x, data$Px, lwd=2)