Why aren't any points showing up in the qqcomp function when using plotstyle="ggplot"? - r

I want to compare the fit of different distributions to my data in a single plot. The qqcomp function from the fitdistrplus package pretty much does exactly what I want to do. The only problem I have however, is that it's mostly written using base R plot and all my other plots are written in ggplot2. I basically just want to customize the qqcomp plots to look like they have been made in ggplot2.
From the documentation (https://www.rdocumentation.org/packages/fitdistrplus/versions/1.0-14/topics/graphcomp) I get that this is totally possible by setting plotstyle="ggplot". If I do this however, no points are showing up on the plot, even though it worked perfectly without the plotstyle argument. Here is a little example to visualize my problem:
library(fitdistrplus)
library(ggplot2)
set.seed(42)
vec <- rgamma(100, shape=2)
fit.norm <- fitdist(vec, "norm")
fit.gamma <- fitdist(vec, "gamma")
fit.weibull <- fitdist(vec, "weibull")
model.list <- list(fit.norm, fit.gamma, fit.weibull)
qqcomp(model.list)
This gives the following output:
While this:
qqcomp(model.list, plotstyle="ggplot")
gives the following output:
Why are the points not showing up? Am I doing something wrong here or is this a bug?
EDIT:
So I haven't figured out why this doesn't work, but there is a pretty easy workaround. The function call qqcomp(model.list, plotstyle="ggplot") still returns an ggplot object, which includes the data used to make the plot. Using that data one can easily write an own plot function that does exactly what one wants. It's not very elegant, but until someone finds out why it's not working as expected I will just use this method.

I was able to reproduce your error and indeed, it's really intriguing. Maybe, you should contact developpers of this package to mention this bug.
Otherwise, if you want to reproduce this qqplot using ggplot and stat_qq, passing the corresponding distribution function and the parameters associated (stored in $estimate):
library(ggplot2)
df = data.frame(vec)
ggplot(df, aes(sample = vec))+
stat_qq(distribution = qgamma, dparams = as.list(fit.gamma$estimate), color = "green")+
stat_qq(distribution = qnorm, dparams = as.list(fit.norm$estimate), color = "red")+
stat_qq(distribution = qweibull, dparams = as.list(fit.weibull$estimate), color = "blue")+
geom_abline(slope = 1, color = "black")+
labs(title = "Q-Q Plots", x = "Theoritical quantiles", y = "Empirical quantiles")
Hope it will help you.

Related

how to mimic histogram plot from flowjo in R using flowCore?

I'm new to flowCore + R. I would like to mimic a histogram plot after gating that can be manually done in FlowJo software. I got something similar but it doesn't look quite right because it is a "density" plot and is shifted. How can I get the x axis to shift over and look similar to how FlowJo outputs the plot? I tried reading this document but couldn't find a plot similar to the one in FlowJo: howtoflowcore Appreciate any guidance. Thanks.
code snippet:
library(flowCore)
parentpath <- "/parent/path"
subfolder <- "Sample 1"
fcs_files <- list.files(paste0(parentpath, subfolder), pattern = ".fcs")
fs <- read.flowSet(fcs_files)
rect.g <- rectangleGate(filterId = "main",list("FSC-A" = c(1e5, 2e5), "SSC-A" = c(3e4,1e5)))
fs_sub <- Subset(fs, rect.g)
p <- ggcyto(fs_sub[[15]], aes(x= `UV-379-A`)) +
geom_density(fill='black', alpha = 0.4) +
ggcyto_par_set(limits = list(x = c(-1e3, 5e4), y = c(0, 6e-5)))
p
FlowJo output:
R FlowCore output:
The reason that for the "shift" is that the x axis is logarithmic (base 10) in the flowJo graph. To achieve the same result in R, add
+ scale_x_log10()
after the existing code. This might interact weirdly with the axis limits you've set, so bare that in mind.
To make the y-axis "count" rather than density, you can change the first line of your ggcyto() call to:
aes(x= `UV-379-A`, y = after_stat(count))
Let me know if that works - I don't have your data to hand so that's all from memory!
For any purely aesthetic changes, they are relatively easy to look up.

Run points() after plot() on a dataframe

I'm new to R and want to plot specific points over an existing plot. I'm using the swiss data frame, which I visualize through the plot(swiss) function.
After this, want to add outliers given by the Mahalanobis distance:
mu_hat <- apply(swiss, 2, mean); sigma_hat <- cov(swiss)
mahalanobis_distance <- mahalanobis(swiss, mu_hat, sigma_hat)
outliers <- swiss[names(mahalanobis_distance[mahalanobis_distance > 10]),]
points(outliers, pch = 'x', col = 'red')
but this last line has no effect, as the outlier points aren't added to the previous plot. I see that if repeat this procedure on a pair of variables, say
plot(swiss[2:3])
points(outliers[2:3], pch = 'x', col = 'red')
the red points are added to the plot.
Ask: is there any restriction to how the points() function can be used for a multivariate data frame?
Here's a solution using GGally::ggpairs. It's a little ugly as we need to modify the ggally_points function to specify the desired color scheme.
I've assumed that mu_hat = colMeans(swiss) and sigma_hat = cov(swiss).
library(dplyr)
library(GGally)
swiss %>%
bind_cols(distance = mahalanobis(swiss, colMeans(swiss), cov(swiss))) %>%
mutate(is_outlier = ifelse(distance > 10, "yes", "no")) %>%
ggpairs(columns = 1:6,
mapping = aes(color = is_outlier),
upper = list(continuous = function(data, mapping, ...) {
ggally_points(data = data, mapping = mapping) +
scale_colour_manual(values = c("black", "red"))
}),
lower = list(continuous = function(data, mapping, ...) {
ggally_points(data = data, mapping = mapping) +
scale_colour_manual(values = c("black", "red"))
}),
axisLabels = "internal")
Unfortunately this isn't possible the way you're currently doing things. When plotting a data frame R produces many plots and aligns them. What you're actually seeing there is 6 by 6 = 36 individual plots which have all been aligned to look nice.
When you use the dots command, it tells it to place the dots on the current plot. Which doesn't really make sense when you have 36 plots, at least not the way you want it to.
ggplot is a really powerful tool in R, it provides far greater combustibility. For example you could set up the dataframe to include your outliers, but have them labelled as "outlier" and place it in each plot that you have set up as facets. The more you explore it you might find there are better plots which suit your needs as well.
Plotting a dataframe in base R is a good exploratory tool. You could set up those outliers as a separate dataframe and plot it, so you can see each of the 6 by 6 plots side by side and compare. It all depends on your goal. If you're goal is to produce exactly as you've described, the ggplot2 package will help you create something more professional. As #Gregor suggested in the comments, looking up the function ggpairs from the GGally package would be a good place to start.
A quick google image search shows some funky plots akin to what you're after and then some!
Find it here

Cannot save plots as pdf when ggplot function is called inside a function

I am going to plot a boxplot from a 4-column matrix pl1 using ggplot with dots on each box. The instruction for plotting is like this:
p1 <- ggplot(pl1, aes(x=factor(Edge_n), y=get(make.names(y_label)), ymax=max(get(make.names(y_label)))*1.05))+
geom_boxplot(aes(fill=method), outlier.shape= NA)+
theme(text = element_text(size=20), aspect.ratio=1)+
xlab("Number of edges")+
ylab(y_label)+
scale_fill_manual(values=color_box)+
geom_point(aes(x=factor(Edge_n), y=get(make.names(true_des)), ymax=max(get(make.names(true_des)))*1.05, color=method),
position = position_dodge(width=0.75))+
scale_color_manual(values=color_pnt)
Then, I use print(p1) to print it on an opened pdf. However, this does not work for me and I get the below error:
Error in make.names(true_des) : object 'true_des' not found
Does anyone can help?
Your example is not very clear because you give a call but you don't show the values of your variables so it's really hard to figure out what you're trying to do (for instance, is method the name of a column in the data frame pl1, or is it a variable (and if it's a variable, what is its type? string? name?)).
Nonetheless, here's an example that should help set you on the way to doing what you want:
Try something like this:
pl1 <- data.frame(Edge_n = sample(5, 20, TRUE), foo = rnorm(20), bar = rnorm(20))
y_label <- 'foo'
ax <- do.call(aes, list(
x=quote(factor(Edge_n)),
y=as.name(y_label),
ymax = substitute(max(y)*1.05, list(y=as.name(y_label)))))
p1 <- ggplot(pl1) + geom_boxplot(ax)
print(p1)
This should get you started to figuring out the rest of what you're trying to do.
Alternately (a different interpretation of your question) is that you may be running into a problem with the environment in which aes evaluates its arguments. See https://github.com/hadley/ggplot2/issues/743 for details. If this is the issue, then the answer might to override the default value of the environment argument to aes, for instance: aes(x=factor(Edge_n), y=get(make.names(y_label)), ymax=max(get(make.names(y_label)))*1.05, environment=environment())

Plotting three densities on the same graph in different line patterns with titles etc

I am very, very new to R so please forgive the basic nature of my question. In short, I have done a lot of Google searching to try to answer this, but I find that even the basic guides available, and simple discussions on forums are assuming more prior knowledge than I have, especially when it comes to outlining what all of the coding terms are and what changing them means for a plot.
In short I have a tab formatted table with three columns of data that I wish to plot densities for on a single graph. I would like the lines to be different patterns (dotted, dashed etc. whatever makes it easy to tell them apart, I cannot use colours as my supervisor is colour blind).
I have code that reads in the data and makes accessible the columns I am interested in:
mydata <- read.table("c:/Users/Demon/Desktop/Thesis/Fst_all_genome.txt", header=TRUE,
sep="\t")
fstdata <- data.frame(Fst_ceu_mkk =rnorm(10),
Fst_ceu_yri =rnorm(10),
Fst_mkk_yri =rnorm(10))
Where do I go from here?
Appendix A of 'An Introduction to R' has a nice walkthrough tutorial you can do in ten minutes; it teaches among other things about line types etc
After that, plotting densities was explained dozens of times here too; search in the search box above for eg '[r] density'. There is also the R Graph Gallery (possibly down right now) and more.
A nice, free guide I often recommend is John Verzani's simpleR which stresses graphs a lot and will teach you what you need here.
Two options for you to explore using high-level graphics.
# dummy data
d = data.frame(x = rnorm(10), y = rnorm(10), z = rnorm(10))
You first need to reshape the data from wide to long format,
require(reshape2)
m = melt(d)
ggplot2 graphics
require(ggplot2)
ggplot(data = m, mapping = aes(x = value, linetype = variable)) +
geom_line(stat = "density")
Lattice graphics
Using the same melt()ed data,
require(lattice)
densityplot( ~ value, data = m, group = variable,
auto.key = TRUE, par.settings = col.whitebg())
If you need something very simple, you could do simply:
plot(density(mydata$col_1))
lines(density(mydata$col_2), lty = 2)
lines(density(mydata$col_2), lty = 3)
If the second and third density curves are far away from the first, you'll need define xy limits of the plotting region explicitly:
dens1 <- density(mydata$col_1)
dens2 <- density(mydata$col_2)
dens3 <- density(mydata$col_3)
plot(dens1, xlim = range(dens1$x, dens2$x, dens3$x),
ylim = range(dens1$y, dens2$y, dens3$y))
lines(density(mydata$col_2), lty = 2)
lines(density(mydata$col_2), lty = 3)
Hope this helps.

Combine two plots created with effects package in R

I have the following Problem. After running an ordered logit model, I want to R's effects package to visualize the results. This works fine and I did so for two independent variables, then I tried to combine the two plots. However, this does not seem to work. I provide a little replicable example here so you can see my problem for yourself:
library(car)
data(Chile)
mod <- polr(vote ~ age + log(income), data=Chile)
eff <- effect("log(income)", mod)
plot1 <- plot(eff, style="stacked",rug=F, key.args=list(space="right"))
eff2 <- effect("age", mod)
plot2 <- plot(eff2, style="stacked",rug=F, key.args=list(space="right"))
I can print these two plots now independently, but when I try to plot them together, the first plot is overwritten. I tried setting par(mfrow=c(2,1)), which didn't work. Next I tried the following:
print(plot1, position=c(0, .5, 1, 1), more=T)
print(plot2, position=c(0,0, 1, .5))
In this latter case, the positions of the two plots are just fine, but still the first plot vanishes once I add the second (or better, it is overwritten). Any suggestions how to prevent this behavior would be appreciated.
Reading down the long list of arguments to ?print.eff we see that there are some arguments for doing just this:
plot(eff, style="stacked",rug=F, key.args=list(space="right"),
row = 1,col = 1,nrow = 1,ncol = 2,more = TRUE)
plot(eff2, style="stacked",rug=F, key.args=list(space="right"),
row = 1,col = 2,nrow = 1,ncol = 2)
The reason par() didn't work is because this package is using lattice graphics, which are based on the grid system, which is incompatible with base graphics. Neither par() nor layout will have any effect on grid graphics.
This seems to work:
plot(eff,col=1,row=2,ncol=1,nrow=2,style="stacked",rug=F,
key.args=list(space="right"),more=T)
plot(eff2,col=1,row=1,ncol=1,nrow=2,style="stacked",rug=F,
key.args=list(space="right"))
edit: Too late...

Resources