Is it possible to force a scale on geom_raster()? - r

I am trying to compare three plots using geom_raster(). The problem is that I would like to maintain the same scale in all three plots that was set in the first plot [-3,3].
Here is my code:
#raster plots
box <- .05
df <- expand.grid(x1 = seq(-1, 1, box), x2 = seq(-1, 1, box))
df$risk <- df$x1 + 2*df$x2
p1 <- ggplot(df, aes(x1, x2, fill = risk)) + geom_raster() +
scale_fill_gradientn(colours=c("#FFFFFF","#046380","#000000")) +
theme_minimal() +
ggtitle("True Risk")
df <- expand.grid(x1 = seq(-1, 1, box), x2 = seq(-1, 1, box))
df$risk <- .99*df$x1 + 1.98*df$x2
p2 <- ggplot(df, aes(x1, x2, fill = risk)) + geom_raster() +
scale_fill_gradientn(colours=c("#FFFFFF","#046380","#000000")) +
theme_minimal() +
ggtitle("Estimated Risk")
df <- expand.grid(x1 = seq(-1, 1, box), x2 = seq(-1, 1, box))
df$risk <- .01*df$x1 + .02*df$x2
p3 <- ggplot(df, aes(x1, x2, fill = risk)) + geom_raster() +
scale_fill_gradientn(colours=c("#FFFFFF","#046380","#000000")) +
theme_minimal() +
ggtitle("Difference")
library(gridExtra)
grid.arrange(p1, p2, p3, ncol=1)
This is my output
It is hard to see that the difference is minimal because the scale changes to [0.03, -0.03]. How can I show the correct surface, but on the original scale?

You can keep all the three variables in one data.frame and use facet_grid or facet_wrap to maintain the scale.
library(ggplot2)
library(reshape2)
box <- .05
df <- expand.grid(x1 = seq(-1, 1, box), x2 = seq(-1, 1, box))
# Calculate each field
df$TrueRisk <- df$x1 + 2*df$x2
df$EstimatedRisk <- .99*df$x1 + 1.98*df$x2
df$Difference <- .01*df$x1 + .02*df$x2
# Transform the data into long format for ggplot2
df <- melt(df, c("x1", "x2"))
# Use facet_grid/facet_wrap to create the plot
ggplot(df, aes(x1, x2, fill = value)) + geom_raster() +
facet_grid(variable ~ .) +
scale_fill_gradientn(colours=c("#FFFFFF","#046380","#000000")) +
theme_minimal() +
ggtitle("Risk")

Related

log_2(x + 1) transformation in ggplot2

I'm trying to implement the log_2(x + 1) transformation in ggplot2 but am running into issues.
Here is an MWE
library(ggplot2)
x <- rexp(100)
y <- rexp(100)
df <- data.frame(x = x, y = y)
p <- ggplot(df, aes(x = x, y = y)) + geom_point(colour = "blue") +
scale_x_continuous(trans = "log2") +
scale_y_continuous(trans = "log2")
print(p)
However, I'm unsure how to best go about transforming the axes, as well as labelling the axes as log_2{x + 1) and log_2(y + 1).
You could use log2_trans from scales with a function to add 1 like this:
library(ggplot2)
library(scales)
x <- rexp(100)
y <- rexp(100)
df <- data.frame(x = x, y = y)
p <- ggplot(df, aes(x = x, y = y)) + geom_point(colour = "blue") +
scale_x_continuous(trans = log2_trans(),
breaks = trans_breaks("log2", function(x) x + 1),
labels = trans_format("log2", math_format(.x + 1))) +
scale_y_continuous(trans = log2_trans(),
breaks = trans_breaks("log2", function(x) x + 1),
labels = trans_format("log2", math_format(.x + 1)))
print(p)
Created on 2022-11-04 with reprex v2.0.2

In R, how do you stack figures made using ggplot2 on top of each other?

I have made two figures in ggplot that I now want to stack on top of each other. I can get them to stack using grid.arrange(p1, p2, ncol =1) function in the gridExtra package however, both figures get horizontally stretched out becoming the shape of rectangles. Any idea on how to keep both figures square (x and y-axes the same overall length).
library(ggplot2)
library(gridExtra)
x1 <- rnorm(20)
y1 <- rnorm(20)
x2 <- rnorm(20)
y2 <- rnorm(20)
dat1 <- data.frame(x1, y1)
dat2 <- data.frame(x2, y2)
p1 <- ggplot(data = dat1, aes(x=x1, y=y1)) + geom_point()
p2 <- ggplot(data = dat2, aes(x=x2, y=y2)) + geom_point()
grid.arrange(p1,p2, ncol=1)
I have tried adjusting the width by using the widths argument but I keep getting the error message Error in arrangeGrob(...) : length(widths) == ncol is not TRUE.
grid.arrange(p1,p2, ncol=1, widths = c(1,1))
The patchwork package is built for this.
Plot1 + Plot2 # side by side
Plot1/Plot2 # top over bottom
I'm a big fan of patchwork for arranging plots. You get square plots by setting the dimensions as you export the figure.
library(patchwork)
p3 <- p1/p2 + plot_layout(ncol = 1, heights = c(1,1))
ggsave("test.png", p3, width = 10, height = 20, units = c("cm"))
Thanks for the responses but I actually figured it out using the packages I mentioned. What I had to do was add theme(aspect.ratio = 1) to both figures.
p1 <- ggplot(data = dat1, aes(x=x1, y=y1)) + geom_point() + theme(aspect.ratio = 1)
p2 <- ggplot(data = dat2, aes(x=x2, y=y2)) + geom_point() + theme(aspect.ratio = 1)
grid.arrange(p1,p2, ncol=1)
How about this:
library(ggplot2)
library(gridExtra)
x1 <- rnorm(20)
y1 <- rnorm(20)
x2 <- rnorm(20)
y2 <- rnorm(20)
dat1 <- data.frame(x1, y1)
dat2 <- data.frame(x2, y2)
p1 <- ggplot(data = dat1, aes(x=x1, y=y1)) + geom_point()
p2 <- ggplot(data = dat2, aes(x=x2, y=y2)) + geom_point()
grid.arrange(p1,p2, ncol=1, widths = unit(10, c("cm")), heights = c(unit(10, c("cm")), unit(10, c("cm"))))

R studio add geom_abline with specified intercept

I want to have a line that crosses the chart at 45 degrees no matter what the x and y scale is. In this example the intercept for the abline shoud be around x=-3 and y=-0.5.
Below a few line of code:
x <- seq(1,10,1)
y <- sample(1:100, 10, replace=T)
df <- data.frame(x,y)
ggplot(df, aes(x=x, y=y)) +
geom_point() +
geom_abline(slope = 45) +
scale_y_continuous(breaks = scales::pretty_breaks(n = 10), limits = c(-10,10)) +
scale_x_continuous(breaks = scales::pretty_breaks(n = 10), limits = c(-2,10))
You would just add
ggplot2::annotation_custom(grid::linesGrob())
to your plot.
So you can do this:
x <- rnorm(100)
y <- rnorm(100)
df <- data.frame(x,y)
ggplot(df, aes(x=x, y=y)) +
geom_point() +
ggplot2::annotation_custom(grid::linesGrob())
or this
ggplot(df, aes(x=x)) +
geom_histogram() +
ggplot2::annotation_custom(grid::linesGrob())
If you want to change the look of the line you need to change the grob:
ggplot(df, aes(x=x, y=y)) +
geom_point() +
ggplot2::annotation_custom(grid::linesGrob(gp = grid::gpar(col = "red", lty = 2)))

Add an exponential line in ggplot that goes through pre-specified points

The code below plots step functions of increasing accuracy toward the underlying polynomial or exponential curve. I am trying to add a curve to my plot that goes through the bottom of each step that I have added.
The commented lines are different attempts that I have tried, but nothing goes exactly through all of the bottom corners of each step down. Is anyone able to help me achieve this? Any help would be greatly appreciated.
library(ggplot2)
X1 <- seq(1, 5, by=0.25)
Y1 <- (0.74 * X^(-2)+0.25)*100
sm <- data.frame(X1, Y1)
X2 <- sort(rep(seq(1, 5, by=0.5), 2))[-18]
Y2 <- sort(rep(Y1[1:17 %% 2 == 1], 2), decreasing = T)[-18]
med <- data.frame(X1, Y2)
X3 <- sort(rep(seq(1,5), 4))[1:17]
Y3 <- sort(rep(Y1[c(1, 5, 9, 13, 17)], 4), decreasing = T)[1:17]
lg <- data.frame(X1, Y3)
ggplot() +
#stat_function(data=sm, mapping = aes(x = X), fun = function(x) {exp(-1*x)*100+28}) +
#geom_curve(aes(x=1, xend=5, y=99, yend=28), ncp = 17) +
#geom_smooth(data = sm, aes(x=X1, y=Y1), method="lm", formula = y ~ poly(x,2), se=F, color= "black", fullrange=T) +
#geom_smooth(data = sm, aes(x=X1, y=Y1), method="lm", formula = (y ~ exp(-1.9*x)), se=F, color= "black", fullrange=T) +
scale_y_continuous(name="Overall Survival (%)", limits=c(0, 100)) +
scale_x_continuous(breaks = seq(from=1, to=5, by=0.25), name = "Survival Time (years)") +
geom_step(colour = "red", size = 1, data = lg, aes(x=X1, y=Y3)) +
geom_step(colour = "purple", size = 1, data = med, aes(x=X1, y=Y2)) +
geom_step(colour = "orange", size = 1, data = sm, aes(x=X1, y=Y1)) +
theme_classic()
I ended up re-doing the initial functions and made it all match up:
MyFunction <- function(x) {100*exp(-(1/4)*x)}
Xyearly <- c(0:5)
Yyearly <- MyFunction(Xyearly)
Yearly <- data.frame(x=Xyearly, y=Yyearly)
X6monthly <- c(0:10/2)
Y6monthly <- MyFunction(X6monthly)
Month6 <- data.frame(x=X6monthly, y=Y6monthly)
X3monthly <- c(0:15/3)
Y3monthly <- MyFunction(X3monthly)
Month3 <- data.frame(x=X3monthly, y=Y3monthly)
X1monthly <- c(0:60/12)
Y1monthly <- MyFunction(X1monthly)
Month1 <- data.frame(x=X1monthly, y=Y1monthly)
ggplot() +
stat_function(data=data.frame(x = 0), mapping = aes(x = x), fun = MyFunction, size=1.2) +
scale_y_continuous(name="Overall Survival (%)", limits=c(0, 100)) +
scale_x_continuous(breaks = seq(from=0, to=5, by=0.5), name = "Survival Time (years)") +
geom_step(colour = "red", size = 1, data = Yearly, aes(x=x, y=y)) +
geom_step(colour = "purple", size = 1, data = Month6, aes(x=x, y=y)) +
geom_step(colour = "orange", size = 1, data = Month3, aes(x=x, y=y)) +
geom_step(colour = "limegreen", size = 1, data = Month1, aes(x=x, y=y))

ggplot: Adding Regression Line Equation and R2 with Facet [duplicate]

This question already has answers here:
Add regression line equation and R^2 on graph
(10 answers)
Closed 9 years ago.
I've created a faceted scatterplot with ggplot but I'm struggling to add the regression line equation to each of the facets. The simple case where there is no faceting has been answered here but this method won't extend to a faceted plot.
Any ideas how to accomplish this in a clean fashion?
Here is an example starting from this answer
require(ggplot2)
require(plyr)
df <- data.frame(x = c(1:100))
df$y <- 2 + 3 * df$x + rnorm(100, sd = 40)
lm_eqn = function(df){
m = lm(y ~ x, df);
eq <- substitute(italic(y) == a + b %.% italic(x)*","~~italic(r)^2~"="~r2,
list(a = format(coef(m)[1], digits = 2),
b = format(coef(m)[2], digits = 2),
r2 = format(summary(m)$r.squared, digits = 3)))
as.character(as.expression(eq));
}
Create two groups on which you want to facet
df$group <- c(rep(1:2,50))
Create the equation labels for the two groups
eq <- ddply(df,.(group),lm_eqn)
And plot
p <- ggplot(data = df, aes(x = x, y = y)) +
geom_smooth(method = "lm", se=FALSE, color="black", formula = y ~ x) +
geom_point()
p1 = p + geom_text(data=eq,aes(x = 25, y = 300,label=V1), parse = TRUE, inherit.aes=FALSE) + facet_grid(group~.)
p1
Does this do what you want?
library(ggplot2); library(gridExtra)
ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
geom_point() +
geom_smooth(method="lm") +
facet_wrap(~ Species)
grid.newpage()
vpa_ <- viewport(width = 1, height = 1)
print(p, vp = vpa_)
grid.text("y ~ mx + b", x=0.3, y=0.8)
grid.text("y ~ mx + b", x=0.5, y=0.8)
grid.text("y ~ mx + b", x=0.8, y=0.8)
Using gridExtra you can arrange yours plots like this.
library(ggplot2)
library(ggplot2)
iris$x = iris$Sepal.Length
iris$y = iris$Sepal.Width
xx <- range(iris$x)
yy <- range(iris$y)
ll <- by(iris,iris$Species,function(df){
x.eq <- max(xx)-mean(xx)/2
y.eq <- max(yy)*0.95
p <- ggplot(df, aes(x, y)) +
geom_point() +
geom_smooth(method="lm") +
annotate(x=x.eq, y =y.eq , geom='text',
label = lm_eqn(df), size=5,parse=TRUE) +
xlim(xx[1],xx[2])+ylim(yy[1],yy[2])
})
library(gridExtra)
do.call(grid.arrange,ll)

Resources