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
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:
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)
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)
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))
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)