I'm trying to augment a plot with contours from a 2D Gaussian distribution with known mean and covariance. Ideally I would just have to specify the function and it would be plotted in 2D (like stat_function
except for 2 dimensions). I can do it with geom_raster
by generating a grid of probabilites. Can I use geom_contour2d
somehow instead?
m <- c(.5, -.5)
sigma <- matrix(c(1,.5,.5,1), nrow=2)
data.grid <- expand.grid(s.1 = seq(-3, 3, length.out=200), s.2 = seq(-3, 3, length.out=200))
q.samp <- cbind(data.grid, prob = mvtnorm::dmvnorm(data.grid, mean = m, sigma = sigma))
ggplot(q.samp, aes(x=s.1, y=s.2)) +
geom_raster(aes(fill = prob)) +
coord_fixed(xlim = c(-3, 3), ylim = c(-3, 3), ratio = 1)
The geom_density_2d_filled function The geom_density_2d function A 2D density contour plot can be created in ggplot2 with geom_density_2d. You just need to pass your data frame and indicate the x and y variable inside aes.
In general, contour plots are useful for functions of two variables (like a bivariate gaussian density). We’ll look at examples in the next section.
The disadvantage with ggplot2 is that it is not possible to get multiple Y-axis on the same plot. To plot multiple time series on the same scale can make few of the series appear small. An alternative would be to facet_wrap it and set the scales='free'.
First, you need to tell ggplot what dataset to use. This is done using the ggplot (df) function, where df is a dataframe that contains all features needed to make the plot. This is the most basic step.
I was barking up the wrong tree looking at 2d
stuff. You can achieve what I want with geom_contour
and by adding a z
aesthetic:
m <- c(.5, -.5)
sigma <- matrix(c(1,.5,.5,1), nrow=2)
data.grid <- expand.grid(s.1 = seq(-3, 3, length.out=200), s.2 = seq(-3, 3, length.out=200))
q.samp <- cbind(data.grid, prob = mvtnorm::dmvnorm(data.grid, mean = m, sigma = sigma))
ggplot(q.samp, aes(x=s.1, y=s.2, z=prob)) +
geom_contour() +
coord_fixed(xlim = c(-3, 3), ylim = c(-3, 3), ratio = 1)
I would use the ellipse
package to construct the contour data directly. This still requires a separate call to construct the data, but is much more efficient (in both space and time) than your solution of constructing an entire grid and then finding the contours.
library(ellipse)
library(plyr) ## not necessary, but convenient
m <- c(.5, -.5)
sigma <- matrix(c(1,.5,.5,1), nrow=2)
alpha_levels <- seq(0.5,0.95,by=0.05) ## or whatever you want
names(alpha_levels) <- alpha_levels ## to get id column in result
contour_data <- ldply(alpha_levels,ellipse,x=sigma,
scale=c(1,1), ## needed for positional matching
centre=m)
(you could use lapply
and rbind
from base R; plyr::ldply
is just a shortcut)
Now plot:
library(ggplot2)
ggplot(contour_data,aes(x,y,group=.id))+geom_path()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With