I have a set of data predicted by a model. I'm plotting it with geom_tile().
df1 <- data.frame(x=rep(seq(0,10,by=.1),each=101),
y=rep(seq(10,20,by=.1),times=101))
df1$z <- ((.1*df1$x^2+df1$y)-10)/20
library("ggplot2")
ggplot(mapping=aes(x=x,y=y,size=5,color=z),data=df1)+
geom_point(size = 16, shape = 15)
ggplot(df1, aes(x, y, fill="blue",alpha = z)) + geom_tile()
How can I add some contour lines to it at specific values (e.g. z=0.9, 0.95, 0.99)? Alternatively, geom_tile can be changed to any suitable continuous / contour / raster plot function.
ggplot(df1, aes(x, y, z = z, fill = z))+
geom_tile()+
geom_contour()
Related
I make a heatmap within ggplot that looks something like that:
set.seed(1)
n <- 100
df <- data.frame(x= rnorm(n), y= rnorm(n), z= rnorm(n))
df$z[1:20] <- NA
ggplot() +
geom_point(data= subset(df, !is.na(z)), mapping= aes(x, y, col= z)) +
geom_point(data= subset(df, is.na(z)), mapping= aes(x, y), col= "black", shape= 4)
Here the points of the scatterplot change colours depending on values in z. Further, I added black crosses (shape 4) to visualize missings in z. I want to add the same x as in the plot to the legend saying missing above it. How can we do this?
I'd actually put the overall command in the same geom_point function using the shape parameter and then manually set the parameters with scale_shape_manual:
ggplot(df) +
geom_point(aes(x, y, colour = z, shape = is.na(z))) +
scale_shape_manual(name = "Missing values", values=c(16, 4))
I want to make a plot using a color palette from packages viridis or RColorBrewer, but I would like to set what point in the variable distribution should be considered as the middle point in the color gradient.
For example, in the following plots, R takes 0.5 to be the middle point of the color range. How can I set a different value, for example, 0.25 ?
library(ggplot2)
library(RColorBrewer)
# data
set.seed(1)
df <- expand.grid(x = 0:5, y = 0:5)
df$z <- runif(nrow(df))
# plot
ggplot(df, aes(x, y, fill = z)) + geom_raster() +
scale_fill_distiller( palette="RdBu", guide = "colorbar")
# plot using viridis
library(viridis)
ggplot(df, aes(x, y, fill = z)) + geom_raster() +
scale_fill_viridis()
EDIT: I was looking for a solution similar to this one here, because the distribution of my variable is not symmetrical. However, I'd like to keep the entire color range from dark blue to dark red, which seems not to be possible.
ggplot(df, aes(x, y, fill = z)) + geom_raster() +
scale_fill_gradient2( low = "#2166ac", mid = "#f7f7f7", high = "#b2182b", midpoint = 0.2,
space = "Lab", na.value = "grey50", guide = "colourbar")
Maybe try setting
space = scale(c(-zlim, 0, zlim))
Where zlim is the extreme value of your data.
I am trying to make a plot using several contour levels with geom_contour. Each of these levels defines a zone onto which I plot points with geom_point. My problem is that I don't manage to have on the same plot a color scale for the points and one for the levels, either the same or another.
MWE:
X <- data.frame(x1 = rnorm(1e4), x2 = rnorm(1e4))
X$z <- sqrt(rowSums(X^2))
X$level <- factor(floor(X$z))
xplot <- yplot <- c(-80:80)/10
df_plot = data.frame(expand.grid(x1=xplot, x2=yplot))
df_plot$z = sqrt(rowSums(df_plot^2))
# plot several contour
ggplot(data = df_plot, aes(x1,x2)) + geom_contour(aes(z=z, color=..level..), breaks = c(1:5))
# plot points with colors corresponding to zone
ggplot(data = X, aes(x1,x2)) + geom_point(aes(color=level))
# plot both
ggplot(data = X, aes(x1,x2)) + geom_point(aes(color=level)) +
geom_contour(data = df_plot, aes(z=z), breaks = 1:5)
On this third plot I'd like to have the levels with the same colors as the points, or at least an other color scale. I've tried to put color= in and out aes but it does not change anything.
thanks
The issue here is that you are mixing a discrete and a continuous colour scale (for the points and the contours, respectively) and ggplot2 uses different defaults for the two. By making the colour scale for the contours discrete as well, you can get the same colours:
ggplot(data = X, aes(x = x1, y = x2)) + geom_point(aes(colour = level)) +
geom_contour(data = df_plot, aes(z = z, colour = factor(..level.. - 1)),
breaks = 0:5, size = 1)
Note that I have reduced the number of points and increased the thickness of the lines to make the lines better visible
This is a slightly long winded way of getting what you want, but you get there in the end.
ggplot(data = X, aes(x1,x2)) +
geom_point(aes(color=level)) + # Now add each contour separately.
geom_contour(data = df_plot, aes(z=z), breaks = 1, colour=rainbow(8)[1]) +
geom_contour(data = df_plot, aes(z=z), breaks = 2, colour=rainbow(8)[2]) +
scale_colour_manual(values=rainbow(8))
I'm a bit stuck plotting a raster with a log scale. Consider this plot for example:
ggplot(faithfuld, aes(waiting, eruptions)) +
geom_raster(aes(fill = density))
But how to use a log scale with this geom? None of the usual methods are very satisfying:
ggplot(faithfuld, aes(waiting, log10(eruptions))) +
geom_raster(aes(fill = density))
ggplot(faithfuld, aes(waiting, (eruptions))) +
geom_raster(aes(fill = density)) +
scale_y_log10()
and this doesn't work at all:
ggplot(faithfuld, aes(waiting, (eruptions))) +
geom_raster(aes(fill = density)) +
coord_trans(x="log10")
Error: geom_raster only works with Cartesian coordinates
Are there any options for using a log scale with a raster?
To be precise, I have three columns of data. The z value is the one I want to use to colour the raster, and it is not computed from the x and y values. So I need to supply all three columns to the ggplot function. For example:
dat <- data.frame(x = rep(1:10, 10),
y = unlist(lapply(1:10, function(i) rep(i, 10))),
z = faithfuld$density[1:100])
ggplot(dat, aes(x = log(x), y = y, fill = z)) +
geom_raster()
What can I do to get rid of those gaps in the raster?
Note that this question is related to these two:
geom_raster interpolation with log scale
Use R to recreate contour plot made in Igor
I have been keeping an updated gist of R code that combines details from the answers to these questions (example output included in the gist). That gist is here: https://gist.github.com/benmarwick/9a54cbd325149a8ff405
The dataset faithfuld already have a column for density which is the estimates of the 2D density for waiting and eruptions. You can find that the eruptions and waiting in the dataset are points in a grid. When you use geom_raster, it doesn't compute the density for you. Instead, it plots the density according to the x, y coordinates, in this case, is the grid. Hence, if you just apply the log transformation on y, it will distort the difference between y (originally they are equally spaced) and this is why you see the space in your plot. I used points to visualize the effects:
library(ggplot2)
library(gridExtra)
# Use point to visualize the effect of log on the dataset
g1 <- ggplot(faithfuld, aes(x=waiting, y=eruptions)) +
geom_point(size=0.5)
g2 <- ggplot(faithfuld, aes(x=waiting, y=log(eruptions))) +
geom_point(size=0.5)
grid.arrange(g1, g2, ncol=2)
If you really want to transform y to log scale and produce the density plot, you have to use the faithful dataset with geom_density_2d.
# Use geom_density_2d
ggplot(faithful, aes(x=waiting, y=log(eruptions))) +
geom_density_2d() +
stat_density_2d(geom="raster", aes(fill=..density..),
contour=FALSE)
Update: Use geom_rect and supply custom xmin, xmax, ymin, ymax values to fit the spaces of the log scale.
Since the geom_raster use the same size of tiles, you probably have to use geom_tile or geom_rect to create the plot. My idea is to calculate how large (width) each tile should be and adjust the xmin and xmax for each tile to fill up the gap.
dat <- data.frame(x = rep(1:10, 10),
y = unlist(lapply(1:10, function(i) rep(i, 10))),
z = faithfuld$density[1:100])
library(ggplot2)
library(gridExtra)
g <- ggplot(dat, aes(x = log(x), y = y, fill = z)) +
geom_raster()
# Replace the ymin and ymax
distance <- diff((unique(dat$x)))/2
upper <- (unique(dat$x)) + c(distance, distance[length(distance)])
lower <- (unique(dat$x)) - c(distance[1], distance)
# Create xmin, xmax, ymin, ymax
dat$xmin <- dat$x - 0.5 # default of geom_raster is 0.5
dat$xmax <- dat$x + 0.5
dat$ymin <- unlist(lapply(lower, function(i) rep(i, rle(dat$y)$lengths[1])))
dat$ymax <- unlist(lapply(upper, function(i) rep(i, rle(dat$y)$lengths[1])))
# You can also use geom_tile with the width argument
g2 <- ggplot(dat, aes(x=log(x), y=y, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, fill=z)) +
geom_rect()
# show the plots
grid.arrange(g, g2, ncol=2)
I have a plot with three different lines. I want one of those lines to have points on as well. I also want the two lines without points to be thicker than the one without points. I have managed to get the plot I want, but I the legend isn't keeping up.
library(ggplot2)
y <- c(1:10, 2:11, 3:12)
x <- c(1:10, 1:10, 1:10)
testnames <- c(rep('mod1', 10), rep('mod2', 10), rep('meas', 10))
df <- data.frame(testnames, y, x)
ggplot(data=df, aes(x=x, y=y, colour=testnames)) +
geom_line(aes(size=testnames)) +
scale_size_manual("", values=c(0.5,1,1)) +
geom_point(aes(alpha=testnames), size=5, shape=4) +
scale_alpha_manual("", values=c(1, 0, 0))
I can remove the second (black) legend:
ggplot(data = df, aes(x=x, y=y, colour=testnames)) +
geom_line(aes(size=testnames)) +
scale_size_manual("", values=c(0.5,1,1), guide='none') +
geom_point(aes(alpha=testnames), size=5, shape=4) +
scale_alpha_manual("", values=c(1, 0.05, 0.05), guide='none')
But what I really want is a merge of the two legends - a legend with colours, cross only on the first variable (meas) and the lines of mod1 and mod2 thicker than the first line. I have tried guide and override, but with little luck.
You don't need transparency to hide the shapes for mod1 and mod2. You can omit these points from the plot and legend by setting their shape to NA in scale_shape_manual:
ggplot(data = df, aes(x = x, y = y, colour = testnames, size = testnames)) +
geom_line() +
geom_point(aes(shape = testnames), size = 5) +
scale_size_manual(values=c(0.5, 2, 2)) +
scale_shape_manual(values=c(8, NA, NA))
This gives the following plot:
NOTE: I used some more distinct values in the size-scale and another shape in order to better illustrate the effect.