I am trying to define a function to produce a scatterplot across the diagonal of a pairs plot. The trick is that I'd like to specify the vertical axis probably in the panel.splot
function. Ultimately I think the use here is to visualize a time series on the diagonal. For a simple example though I'd like to try this with the iris dataset and use Species
as the vertical axis variable. The plot below produces a nice looking plot:
pairs(iris[,c(1:4)])
So now I'd need to define a function for the diagonal panel. Here is my efforts so far:
panel.splot <- function(x, yvar,...)
{
usr <- par("usr"); on.exit(par(usr))
par(usr = c(0, 2, usr[3:4]))
plot(yvar,x, xlim=c(min(x),max(x)))
}
However, when I try to run it, I get an error message that I'm not sure how to interpret.
pairs(iris[,c(1:4)],diag.panel=panel.splot(x=x, yvar="Species"))
Error in plot.window(...) : invalid 'xlim' value
In addition: Warning messages:
1: In xy.coords(x, y, xlabel, ylabel, log) : NAs introduced by coercion
2: In xy.coords(x, y, xlabel, ylabel, log) : NAs introduced by coercion
3: In min(x) : no non-missing arguments to min; returning Inf
4: In max(x) : no non-missing arguments to max; returning -Inf
I haven't been able to find another example of this. Lots of other functions to create different types of plots but nothing that does exactly this.
For clarity, this is the type of plot I am imagining would be produced along the diagonal of the pairs()
call:
plot(iris$Species,iris$Petal.Width)
Despite your example plot, i interpreted this slightly differently (incorrectly) due to use Species as the vertical axis variable . Hubert's given the answer but thought it might add something.
Using pairs()
panel.splot <- function(Y, Adjust=0.2){
function(x, y=Y, adjust=Adjust)
{
usr <- par("usr"); on.exit(par(usr))
xs <- range(x)
ys <- if(is.factor(y)) c(1, nlevels(y)) else range(y)
par(usr = c(xs[1], xs[2], ys[1], ys[2]) + c(-adjust, adjust))
points(x, y)
}
}
pairs(iris[, 1:4], diag.panel=panel.splot(Y=iris$Species))
Which produces
To do the same thing with ggpairs()
you can also define a user function
library(GGally)
library(ggplot2)
# Define diagonal function
diag_fun <- function(data, mapping, ...){
ggplot(data = data, mapping = mapping) +
geom_point(...)
}
ggpairs(iris, columns=1:4,
diag = list(continuous = diag_fun, mapping=aes(y=Species)))
Which gives
Update for your comments...
Yes, for the diagonal entries, the variable is passed as the x
mapping. You can either use coord_flip()
or reverse the mapping in the function. The function below does this, and adds the variable names using annotate()
(ps. you should be able to swap out the _point
geom for say, _boxplot
diag_fun <- function(data, mapping, xnudge=0.95, ynudge=1, pts=lst(), ...){
# create range for annotate
lbl <- as.character(mapping$x)
xmax <- max(data[, as.character(mapping$x)], na.rm=TRUE)
ymax <- mean(seq(nlevels(data[,as.character(mapping$y)])))
# reverse mapping so no need for coord_flip()
tmp <- mapping$y
mapping$y <- mapping$x
mapping$x <- tmp
ggplot(data=data, mapping=mapping) +
do.call(geom_point, pts) +
annotate("text", x=ynudge*ymax, y=xnudge*xmax, label=lbl, ...)
}
So to use it in ggpairs
with the defaults
ggpairs(iris, columns=1:4, diag = list(continuous = diag_fun, mapping=aes(y=Species)))
And you can use wrap
to pass further arguments
ggpairs(iris, columns=1:4,
diag = list(continuous =
wrap(diag_fun,
size=10, col="red", # make changes to the text label
pts=list(colour="blue")), # make changes to geom_point
mapping=aes(y=Species)))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.