Plot a point in a contour plot ggplot2 - r

I have a contour plot in ggplot2 that I want to map one point to.
My contour plot looks like this:
v = ggplot(pts, aes(theta_1, theta_2, z = z))
v + stat_contour(aes(colour = ..level..),bins=50)
+ xlab(expression(Theta[1])) + ylab(expression(Theta[2]))
and I have a point that looks like this:
p = ggplot(ts,aes(x,y))
p + geom_point()
unfortunately the second overwrites the first.
Is there a way to get them to show up on the same plot, similar to MATLAB's "hold on;"?
Thanks!

You can provide the points directly to geom_point():
set.seed(1000)
x = rnorm(1000)
g = ggplot(as.data.frame(x), aes(x = x))
g + stat_bin() + geom_point(data = data.frame(x = -1, y = 40), aes(x=x,y=y))

Not sure if this is still of interest, but I think you just needed to save the updated v object then add the point to that, rather than create a new ggplot2 object. For example
v <- ggplot(pts, aes(theta_1, theta_2, z = z))
v <- v + stat_contour(aes(colour = ..level..),bins=50)
+ xlab(expression(Theta[1])) + ylab(expression(Theta[2]))
v <- v + geom_point(aes(x=ts$x, y=ts$y))
v # to display
ggplot2 is very good at adding layers incrementally, not all have to be based on the same dataset specified in the first ggplot call.

Related

How to plot two distribution curves in a faceted way in R / ggplot2?

I have two probability distribution curves, a Gamma and a standarized Normal, that I need to compare:
library(ggplot2)
pgammaX <- function(x) pgamma(x, shape = 64.57849, scale = 0.08854802)
f <- ggplot(data.frame(x=c(-4, 9)), aes(x)) + stat_function(fun=pgammaX)
f + stat_function(fun = pnorm)
The output is like this
However I need to have the two curves separated by means of the faceting mechanism provided by ggplot2, sharing the Y axis, in a way like shown below:
I know how to do the faceting if the depicted graphics come from data (i.e., from a data.frame), but I don't understand how to do it in a case like this, when the graphics are generated on line by functions. Do you have any idea on this?
you can generate the data similar to what stat_function is doing ahead of time, something like:
x <- seq(-4,9,0.1)
dat <- data.frame(p = c(pnorm(x), pgammaX(x)), g = rep(c(0,1), each = 131), x = rep(x, 2) )
ggplot(dat)+geom_line(aes(x,p, group = g)) + facet_grid(~g)
The issue with doing facet_wrap is that the same stat_function is designed to be applied to each panel of the faceted variable which you don't have.
I would instead plot them separately and use grid.arrange to combine them.
f1 <- ggplot(data.frame(x=c(-4, 9)), aes(x)) + stat_function(fun = pgammaX) + ggtitle("Gamma") + theme(plot.title = element_text(hjust = 0.5))
f2 <- ggplot(data.frame(x=c(-4, 9)), aes(x)) + stat_function(fun = pnorm) + ggtitle("Norm") + theme(plot.title = element_text(hjust = 0.5))
library(gridExtra)
grid.arrange(f1, f2, ncol=2)
Otherwise create the data frame with y values from both pgammaX and pnorm and categorize them under a faceting variable.
Finally I got the answer. First, I need to have two data sets and attach each function to each data set, as follows:
library(ggplot2)
pgammaX <- function(x) pgamma(x, shape = 64.57849, scale = 0.08854802)
a <- data.frame(x=c(3,9), category="Gamma")
b <- data.frame(x=c(-4,4), category="Normal")
f <- ggplot(a, aes(x)) + stat_function(fun=pgammaX) + stat_function(data = b, mapping = aes(x), fun = pnorm)
Then, using facet_wrap(), I separate into two graphics according to the category assigned to each data set, and establishing a free_x scale.
f + facet_wrap("category", scales = "free_x")
The result is shown below:

R: ggplot distance formula

I'm trying to plot isoclines under a scatterplot using ggplot but I can't figure out how to use stat_functioncorrectly.
The isoclines are based on the distance formula:
sqrt((x1-x2)^2 + (y1-y2)^2)
and would look like these
concentric circles, except the center would be the origin of the plot:
What I've tried so far is calling the distance function within ggplot like so (Note: I use x1=1 and y1=1 because in my real problem I also have fixed values)
distance <- function(x, y) {sqrt((x - 1)^2 + (y - 1)^2)}
ggplot(my_data, aes(x, y))+
geom_point()+
stat_function(fun=distance)
but R returns the error:
Computation failed in 'stat_function()': argument "y" is missing, with
no default
How do I correctly feed x and y values to stat_function so that it plots a generic plot of the distance formula, with the center at the origin?
For anything a bit complicated, I avoid the use of the stat functions. They are mostly aimed at quick calculations. They are usually limited to calculating y based on x. I would just pre-calculate the data and the plot with stat_contour instead:
distance <- function(x, y) {sqrt((x - 1)^2 + (y - 1)^2)}
d <- expand.grid(x = seq(0, 2, 0.02), y = seq(0, 2, 0.02))
d$dist <- mapply(distance, x = d$x, y = d$y)
ggplot(d, aes(x, y)) +
geom_raster(aes(fill = dist), interpolate = T) +
stat_contour(aes(z = dist), col = 'white') +
coord_fixed() +
viridis::scale_fill_viridis(direction = -1)

How to make ggplot lines run to the edge?

I have data (depth over time) that I want to display with a line plot. For clarity, I want to zoom in on a section but still show the user that the data continues outside the bounds of the plot. So I want the lines to stop at the plot's edge, rather than at the last point. This is straightforward enough in base graphics but I can't make it work in ggplot. Here's an example with base:
d <- data.frame(x = 1:10, y = 1:10)
plot(d$x, d$y, xlim = c(2,9))
lines(d$x, d$y)
A similar approach with ggplot doesn't work; the lines stop at the last point. Example:
d <- data.frame(x = 1:10, y = 1:10)
ggplot(d, aes(x, y)) + geom_point() + geom_line() + xlim(2,9)
Is there a way to get lines to run to the plot's edge in ggplot? Thanks.
try this
d <- data.frame(x = 1:10, y = 1:10)
ggplot(d, aes(x, y)) + geom_point() + geom_line() + coord_cartesian(xlim = c(0,9))
if you want a straight line, abline would be easiest
d <- data.frame(x = 1:10, y = 1:10)
ggplot(d, aes(x, y)) + geom_point() + geom_abline() + xlim(2,9)

How to underline text in a plot title or label? (ggplot2)

Please pardon my ignorance if this is a simple question, but I can't seem to figure out how to underline any part of a plot title. I'm using ggplot2.
The best I could find was
annotate("segment") done by hand, and I have created a toy plot to illustrate its method.
df <- data.frame(x = 1:10, y = 1:10)
rngx <- 0.5 * range(df$x)[2] # store mid-point of plot based on x-axis value
rngy <- 0.5 * range(df$y)[2] # stores mid-point of y-axis for use in ggplot
ggplot(df, aes(x = x, y = y)) +
geom_point() +
ggtitle("Oh how I wish for ..." ) +
ggplot2::annotate("text", x = rngx, y = max(df$y) + 1, label = "underlining!", color = "red") +
# create underline:
ggplot2::annotate("segment", x = rngx-0.8, xend = rngx + 0.8, y= 10.1, yend=10.1)
uses bquote(underline() with base R
pertains to lines over and under nodes on a graph
uses plotmath and offers a workaround, but it didn't help
Try this:
ggplot(df, aes(x = x, y = y)) + geom_point() +
ggtitle(expression(paste("Oh how I wish for ", underline(underlining))))
Alternatively, as BondedDust points out in the comments, you can avoid the paste() call entirely, but watch out for the for:
ggplot(df, aes(x = x, y = y)) + geom_point() +
ggtitle(expression(Oh~how~I~wish~'for'~underline(underlining)))
Or another, even shorter approach suggested by baptiste that doesn't use expression, paste(), or the many tildes:
ggplot(df, aes(x = x, y = y)) + geom_point() +
ggtitle(~"Oh how I wish for "*underline(underlining))

Multiple layers in ggplot2 with different datasets

I have a contour plot and I would like to add a geom_path with a different set of data over it.
Right now I have the below code, but as soon as it gets to the geom_path, it overwrites the contour plot. Is there a way to prevent this from happening?
v <- ggplot(pts, aes(theta_1, theta_2, z = z))
v + stat_contour(aes(colour = ..level..),bins=50) + xlab(expression(Theta[1])) + ylab(expression(Theta[2]))
v+geom_path(aes(x=x,y=y,z=z), data=some.mat)
probably you can do by:
v <- ggplot(pts, aes(theta_1, theta_2, z = z))
v <- v + stat_contour(aes(colour = ..level..),bins=50) + xlab(expression(Theta[1])) + ylab(expression(Theta[2]))
v + geom_path(aes(x=x,y=y,z=z), data=some.mat)

Resources