I generated one data
nitrogen<- c(0,40,80,120,160,260)
yield <- c(8.4,9.8,10.8,12.5,11.1,12.7)
dataA<- data.frame(nitrogen, yield)
and I'd like to see this data as quadratic-plateau model. So I used nlsplot() code.
install.packages("easynls")
library(easynls)
nlsplot(dataA, model=4)
The model equation is covered in the graph. I'd like to see the full model equation about this quadratic-plateau model.
Could you let me know how to do it?
Always many thanks!!
One solution could be using par() function to adjust the plot size and font size arguments within par() and then run nlsplot():
# change the font size for the plot
par(cex.lab = 1.5, cex.axis = 1.5, cex=1.2)
# plot the data with formula
nlsplot(dataA, model = 4)
Now I change the font size of the formula to 0.8 to cover better.You can play with the par() arguments to adjust your plot.
par(cex.lab = 1, cex.axis = 1, cex=0.8)
nlsplot(dataA, model = 4)
Related
I'm doing microssatellite analysis to understand genetic relationship between fungal isolates. For that I first calculated the Jaccard’s coefficient and then want to generate a dendrogram using UPGMA cluster analysis.
I did the following:
Distance matrix computation
jacc_coef <- vegdist(HC_df, method = "jaccard") *100
(HC_df is my data frame)
Hierarchical clustering
afu_clin.hc <- hclust(d = jacc_coef, method = "average")
When I plot afu_clin.hc with another package I obtain the heigth scale corresponding to the % of dissimilarity that was calculated before.
HC <- fviz_dend(x = afu_clin.hc, cex = 0.7, lwd = 0.7, horiz = TRUE)
print(HC)
I obtain the following plot:
enter image description here
However, when I try to use the ggtree the scale is different. I'm wondering how can I use ggtree to display my dendrogram with the height scale as % dissimilarity calculated with Jaccard’s coefficient.
I used this code:
hc_tree <- ggtree(afu_clin.hc, size =0.8) + geom_tiplab(angle = 90, hjust=1, offset=-.05) + layout_dendrogram() + theme_dendrogram()
obtained this plot (I don't understand this scale, where does it come from?)
enter image description here
How can I use ggtree to plot a similar dendrogram to the one that I showed first?
Thank you,
Best
Daryna
I'm really new to R and I'm looking to create a graph similar to the one attached. I have tried to create a density plot using both ggplot and the base program.
I have used code ggplot(data, aes(x = Freq)) + geom_density() but the output is incorrect. I'm getting a spike at each number point rather than an overall curve. Every row is one data point of between 1 to 7 and the frequency distributions for one trait is as follows:
1: 500, 2: 550 3:700 4:1000 5:900 6:835: 7:550
As such I have 5035 rows as one row equates to one score.
Any help is much appreciated.
Here is what I wish the plot would look like. (Note I'll add other traits at a later stage, I just wish to add one line at the moment).
there are a few things going on here, first is generating summary statistics of the data. you just need to call mean and sd in the appropriate way to get mean and standard deviation from your data. you've not shown your data so it would be difficult to suggest much here.
as far as plotting these summary statistics, you can replicate the plot from the original paper easily, but it's pretty bad and I'd suggest you not do that. stronger lines imply more importance, the need to double label everything, mislabelling the y-axis, all of that on top of drawing nice smooth parametric curves gives a false impression of confidence. I've only scanned the paper, but that sort of data is crying out for a multi-level model of some sort
I prefer "base" graphics, ggplot is great for exploratory graphics but if you have hard constraints on what a plot should look like it tends to get in the way. We start with the summary statistics:
df <- read.csv(text="
title, mu, sigma,label, label_x,label_pos
Extraversion, 4.0, 1.08,Extra, 3.85,3
Agreeableness, 5.0, 0.77,Agree, 5.0, 3
Conscientiousness, 4.7, 0.97,Cons, 3.4, 2
Emotional stability,5.3, 0.84,Emot stab,5.9, 4
Intellect, 3.7, 0.86,Intellect,3.7, 3
")
I've just pulled numbers out of the paper here, you'd have to calcular them. the mu column is the mean of the variable, and sigma is the standard deviation. label_x and label_pos are used to draw labels so need to be manually chosen (or the plot can be annotated afterwards in something like Inkscape). label_x is the x-axis position, and label_pos stands for where it is in relation to the x-y point (see text for info about the pos parameter)
next we calculate a couple of things:
lwds <- 1 + seq(3, 1, len=5) ^ 2
label_y <- dnorm(df$label_x, df$mu, df$sigma)
i.e. line widths and label y positions, and we can start to make the plot:
# start by setting up plot nicely and setting plot limits
par(bty='l', mar=c(3, 3, 0.5, 0.5), mgp=c(1.8, 0.4, 0), tck=-0.02)
plot.new(); plot.window(c(1, 7), c(0, 0.56), yaxs='i')
# loop over data drawing curves
for (i in 1:nrow(df)) {
curve(dnorm(x, df$mu[[i]], df$sigma[[i]]), add=T, n=151, lwd=lwds[[i]])
}
# draw labels
text(df$label_x, label_y, df$label, pos=df$label_pos)
# draw axes
axis(1, lwd=0, lwd.ticks=1)
axis(2, lwd=0, lwd.ticks=1)
box(lwd=1)
# finally, title and legend
title(xlab='Level of state', ylab='Probability density')
legend('topleft', legend=df$title, lwd=lwds, bty='n', cex=0.85)
this gives us something like:
I've also gone with more modern capitalisation, and started the y-axis at zero as these are probabilities so can't be negative
My preferences would be for something closer to this:
the thin lines cover 2 standard deviations (i.e. 95% intervals) around the mean, thick lines 1 SDs (68%), and the point is the mean. it's much easier to discriminate each measure and compare across them, and it doesn't artificially make "extraversion" more prominent. the code for this is similar:
par(bty='l', mar=c(3, 8, 0.5, 0.5), mgp=c(1.8, 0.4, 0), tck=-0.02)
plot.new(); plot.window(c(1, 7), c(5.3, 0.7))
# draw quantiles
for (i in 1:nrow(df)) {
lines(df$mu[[i]] + df$sigma[[i]] * c(-1, 1), rep(i,2), lwd=3)
lines(df$mu[[i]] + df$sigma[[i]] * c(-2, 2), rep(i,2), lwd=1)
}
# and means
points(df$mu, 1:5, pch=20)
axis(1, lwd=0, lwd.ticks=1)
axis(2, at=1:5, labels=df$title, lwd=0, lwd.ticks=1, las=1)
box()
title(xlab='Level of state')
I am using the following code to plot the ROC curve after having run the logistic regression.
fit1 <- glm(formula=GB160M3~Behvscore, data=eflscr,family="binomial", na.action = na.exclude)
prob1=predict(fit1, type=c("response"))
eflscr$prob1 = prob1
library(pROC)
g1 <- roc(GB160M3~prob1, data=eflscr, plot=TRUE, grid=TRUE, print.auc=TRUE)
The ROC curves plotted look like this (see link below)
The x-axis scale does not fill the who chart.
How can I change the x axis to report 1 - specifically?
By default pROC sets asp = 1 to ensure the plot is square and both sensitivity and specificity are on the same scale. You can set it to NA or NULL to free the axis and fill the chart, but your ROC curve will be misshaped.
plot(g1, asp = NA)
Using par(pty="s") as suggested by Joe is probably a better approach
This is purely a labeling problem: note that the x axis goes decreasing from 1 to 0, which is exactly the same as plotting 1-specificity on an increasing axis. You can set the legacy.axes argument to TRUE to change the behavior if the default one bothers you.
plot(g1, legacy.axes = TRUE)
A good shortcut to getting a square plot is to run the following before plotting:
par(pty="s")
This forces the shape of the plot region to be square. Set the plotting region back to maximal by simply resetting the graphics device and clearing the plot.
dev.off()
As pointed out by #Calimo, there is the legacy.axes argument to reverse the x-axis and the label is also changed automatically. You can run ?plot.roc to see all the pROC plotting options.
Example
# Get ROC object
data(aSAH)
roc1 <- roc(aSAH$outcome, aSAH$s100b)
# Plot
par(pty="s")
plot(roc1, grid = TRUE, legacy.axes = TRUE)
# Reset graphics device and clear plot
dev.off()
I want to plot the histogram with real data and compare it with a theoretical normal distribution in one plot. But the scale looks different. Two plots have different scale
# you can generate some ramdom data on ystar which is realy data.
x<-seq(-4,4,length=200)
y<-dnorm(x,mean=0, sd=1)
plot(x,y, type = "l", lwd = 2, xlim = c(-3.5,3.5),ylim=c(0,0.7))
par(new = TRUE)
hist(ystar,xlim = c(-10,10),freq = FALSE,ylim=c(0,0.7),breaks = 50)
Desire output
Assuming that ystar is a vector, you should change this:
y<-dnorm(x,mean=0, sd=1)
To:
y<-dnorm(x,mean=mean(ystar), sd=sd(ystar))
This will produce a distribution function that approximately matches the histogram.
You should then be able to use the same x-limits for both the histogram and the theoretical distribution, which will eliminate the strange overlapping axis labels you have in your current version.
I am using filled.contour() to plot data stored in a matrix. The data is generated by a (highly) non-linear function, hence its distribution is not uniform at all and the range is very large.
Consequently, I have to use the option "levels" to fine tune the plot. However, filled.contour() does not use these custom levels to make an appropriate color key for the heat map, which I find quite surprising.
Here is a simple example of what I mean:
x = c(20:200/100)
y = c(20:200/100)
z = as.matrix(exp(x^2)) %*% exp(y^2)
filled.contour(x=x,y=y,z=z,color.palette=colorRampPalette(c('green','yellow','red')),levels=c(1:60/3,30,50,150,250,1000,3000))
As you can see, the color key produced with the code above is pretty much useless. I would like to use some sort of projection (perhaps sin(x) or tanh(x)?), so that the upper range is not over-represented in the key (in a linear way).
At this point, I would like to:
1) know if there is something very simple/obvious I am missing, e.g.: an option to make this "key range adapting" automagically;
2) seek suggestions/help on how to do it myself, should the answer to 1) be negative.
Thanks a lot!
PS: I apologize for my English, which is far from perfect. Please let me know if you need me to clarify anything.
I feel your frustration. I never found a way to do this with filled contour, so have usually reverted to using image and then adding my own scale as a separate plot. I wrote the function image.scale to help out with this (link). Below is an example of how you can supply a log-transform to your scale in order to stretch out the small values - then label the scale with the non-log-transformed values as labels:
Example:
source("image.scale.R") # http://menugget.blogspot.de/2011/08/adding-scale-to-image-plot.html
x = c(20:200/100)
y = c(20:200/100)
z = as.matrix(exp(x^2)) %*% exp(y^2)
pal <- colorRampPalette(c('green','yellow','red'))
breaks <- c(1:60/3,30,50,150,250,1000,3000)
ncolors <- length(breaks)-1
labs <- c(0.5, 1, 3,30,50,150,250,1000,3000)
#x11(width=6, height=6)
layout(matrix(1:2, nrow=1, ncol=2), widths=c(5,1), heights=c(6))
layout.show(2)
par(mar=c(5,5,1,1))
image(x=x,y=y,z=log(z), col=pal(ncolors), breaks=log(breaks))
box()
par(mar=c(5,0,1,4))
image.scale(log(z), col=pal(ncolors), breaks=log(breaks), horiz=FALSE, xlab="", ylab="", xaxt="n", yaxt="n")
axis(4, at=log(labs), labels=labs)
box()
Result: