Combining 2 normal probability plots in same ggplot - r

I have 2 normal probability plots as below
library(ggplot2)
# Plot 1
ggplot(data.frame(x = c(-4, 4)), aes(x)) +
stat_function(fun = dnorm, args = list(mean = 0, sd = 1), col='red') +
stat_function(fill='red', fun = dnorm, xlim = c(-4, -1), geom = "area") +
stat_function(fill='red', fun = dnorm, xlim = c(-1, 4), geom = "area", alpha = 0.3)
# Plot 2
ggplot(data.frame(x = c(-4, 4)), aes(x)) +
stat_function(fun = dnorm, args = list(mean = 0, sd = 2), col='blue') +
stat_function(fill='blue', fun = dnorm, args = list(mean = 0, sd = 2), xlim = c(-4, -1), geom = "area") +
stat_function(fill='blue', fun = dnorm, args = list(mean = 0, sd = 2), xlim = c(-1, 4), geom = "area", alpha = 0.3)
Individually they are just fine. However I wanted to combine these 2 plots and place them in same plot window with same x-axis.
I also want to add a legend based on fill color in the combined plot to distinguish them.
Is there any way to achieve this with ggplot?
Any pointer will be very helpful

You could combine both the stat_functions and create two with an aes for your fill to create a legend with scale_fill_manual like this:
library(ggplot2)
ggplot(data.frame(x = c(-4, 4)), aes(x)) +
stat_function(fun = dnorm, args = list(mean = 0, sd = 1), col='red') +
stat_function(fun = dnorm, xlim = c(-4, -1), geom = "area", aes(fill = "plot 1")) +
stat_function(fill='red', fun = dnorm, xlim = c(-1, 4), geom = "area", alpha = 0.3) +
stat_function(fun = dnorm, args = list(mean = 0, sd = 2), col='blue') +
stat_function(fun = dnorm, args = list(mean = 0, sd = 2), xlim = c(-4, -1), geom = "area", aes(fill = "plot 2")) +
stat_function(fill='blue', fun = dnorm, args = list(mean = 0, sd = 2), xlim = c(-1, 4), geom = "area", alpha = 0.3) +
scale_fill_manual(name = "Legend", values = c("red", "blue"))
Created on 2022-12-31 with reprex v2.0.2

Related

Limiting vertical line length in R ggplot2

I am trying to draw a forest plot with different groups. The code I'm using looks like the following:
d = data.frame(Estimate = c(1.8,1.9,2.1,2.4,2.7,2.5),
Group = rep(c('Group A', 'Group B'), each = 3),
Method = rep(c('Method 1', 'Method 2', 'Method 3'), 2))
d$Lower = d$Estimate - 0.3
d$Upper = d$Estimate + 0.3
ggplot(data = d, aes(y = Group, x = Estimate, xmin = Lower, xmax = Upper, color = Method)) +
geom_point(size = 2, position=position_dodge(width = 0.5)) +
geom_linerange(position=position_dodge(width = 0.5)) +
geom_vline(xintercept = c(2, 2.5), linetype = "dashed")
And the resulting plot:
The vertical lines (2, 2.5) are the true group means. I want to limit these vertical lines to be within each group (i.e., the first one from bottom to the middle, the second one middle to top). Anyone know how to do this?
I've tried geom_segment() function but I think it requires a numerical y input, while it's a factor here.
Factors plotted on an axis are "really" numeric, but with labels added, so you can go ahead and add numeric segments:
ggplot(data = d, aes(y = Group, x = Estimate, xmin = Lower, xmax = Upper,
color = Method)) +
geom_point(size = 2, position=position_dodge(width = 0.5)) +
geom_linerange(position=position_dodge(width = 0.5)) +
geom_segment(data = data.frame(y = c(0.67, 1.67), x = c(2, 2.5),
xend = c(2, 2.5), yend = c(1.33, 2.33)),
aes(x, y, xend = xend, yend = yend),
inherit.aes = FALSE, linetype = 2)
Or, with a few tweaks:
ggplot(data = d, aes(y = Group, x = Estimate, xmin = Lower, xmax = Upper,
color = Method)) +
geom_linerange(position=position_dodge(width = 0.5), size = 1) +
geom_point(size = 3, position=position_dodge(width = 0.5), shape = 21,
fill = "white") +
geom_segment(data = data.frame(y = c(0.67, 1.67), x = c(2, 2.5),
xend = c(2, 2.5), yend = c(1.33, 2.33)),
aes(x, y, xend = xend, yend = yend),
inherit.aes = FALSE, linetype = 2) +
annotate("text", c(2, 2.5), c(1.5, 2.5), size = 6,
label = c("Group mean = 2", "Group mean = 2.5")) +
theme_minimal(base_size = 20) +
scale_color_brewer(palette = "Set1")

How to add a custom legend to multiple geom_function()?

library(tidyverse)
ggplot(data = data.frame(x = c(0, 1)), aes(x)) +
geom_function(fun = dnorm, n = 10001,
args = list(mean = .5, sd = .125),
show.legend = T) +
geom_function(fun = dbeta, n = 10001,
args = list(shape1 = 10, shape2 = 8),
linetype = 5, show.legend = T) +
geom_function(fun = dbeta, n = 10001,
args = list(shape1 = 15, shape2 = 8),
linetype = 2, show.legend = T) +
geom_function(fun = dbeta, n = 10001,
args = list(shape1 = 20, shape2 = 8),
linetype = 3, show.legend = T) +
ylab("f(θ)") +
xlab("θ") +
scale_linetype_manual(
values = c("a" = 1,
"b" = 5,
"c" = 2,
"d" = 3)
)+
theme_test(base_size = 20)
If you plot this, the legend will not take the correct linetypes. It will always show the linetype "1" or "solid".
How do I show different correct linetypes in scale_linetype_manual()?
If you want to have a legend you have to map on aesthetics, i.e. instead of setting the linetype as parameter set it inside aes() and use the labels you used in scale_linetype_manual:
Note: Doing we could get rid of show.legend=T as ggplot will automatically add a legend.
library(ggplot2)
ggplot(data = data.frame(x = c(0, 1)), aes(x)) +
geom_function(aes(linetype = "a"), fun = dnorm, n = 10001,
args = list(mean = .5, sd = .125)) +
geom_function(aes(linetype = "b"), fun = dbeta, n = 10001,
args = list(shape1 = 10, shape2 = 8)) +
geom_function(aes(linetype = "c"), fun = dbeta, n = 10001,
args = list(shape1 = 15, shape2 = 8)) +
geom_function(aes(linetype = "d"), fun = dbeta, n = 10001,
args = list(shape1 = 20, shape2 = 8)) +
ylab("f(θ)") +
xlab("θ") +
scale_linetype_manual(
values = c("a" = 1,
"b" = 5,
"c" = 2,
"d" = 3)
)+
theme_test(base_size = 20)
EDIT Instead of mapping on the linetype aesthetic another option would be to set your desired linetype via the override.aes argument of guide_legend. This could also be used to set different colors or ... . But be aware that doing so you have to set the linetypes in the order the categories appear in the legend:
Note: The assignment of linetype via the scale does not work. For this we have to map on aesthetics.
library(ggplot2)
ggplot(data = data.frame(x = c(0, 1)), aes(x)) +
geom_function(fun = dnorm, n = 10001,
args = list(mean = .5, sd = .125),
show.legend = T, linetype = 3) +
geom_function(fun = dbeta, n = 10001,
args = list(shape1 = 10, shape2 = 8),
linetype = 5) +
geom_function(fun = dbeta, n = 10001,
args = list(shape1 = 15, shape2 = 8),
linetype = 2) +
geom_function(fun = dbeta, n = 10001,
args = list(shape1 = 20, shape2 = 8),
linetype = 3) +
ylab("f(θ)") +
xlab("θ") +
scale_linetype_manual(
values = c("a" = 1,
"b" = 2,
"c" = 2,
"d" = 3)
)+
theme_test(base_size = 20) +
guides(linetype = guide_legend(override.aes = list(linetype = c(1, 5, 2, 3), color = c(1, 5, 2, 3))))

How can I add a legend to indicate a color code instead of data?

I am struggling to add a color code (legend) to the plot created with the PwrPlot() function shown below. This is for a teaching demonstration and I just need to replace the labels (alpha, beta, 1-alpha, 1-beta) by a legend indicating what each color refers to (indeed, changing the parameters of the curves could result in some 'ugly' label positions in the graph!). And running this function also gives out warnings that I can't interpret:
Warning messages:
1: In is.na(x) :
is.na() applied to non-(list or vector) of type 'expression'
Any help would be greatly appreciated! Thanks
PwrPlot <- function(mu0=0, mu1=1.9, sig0=1, sig1=1, alpha=0.05, tail=1){
ggplot(data.frame(x = -4:5), aes(x)) +
stat_function(fun = dnorm, args = c(mu0, sig0), geom = 'area',
xlim = c(qnorm(1-alpha/tail, mu0, sig0), 5), fill = 'red') +
stat_function(fun = dnorm, args = c(mu0, sig0)) +
stat_function(fun = dnorm, args = c(mu0, sig0), geom = 'area',
xlim = c(-4, qnorm(1-alpha/tail, mu0, sig0)), fill = 'deepskyblue3') +
stat_function(fun = dnorm, args = c(mu0, sig0)) +
stat_function(fun = dnorm, args = c(mu1, sig1)) +
stat_function(fun = dnorm, args = c(mu1, sig1), geom = 'area',
xlim = c(qnorm(1-alpha/tail, mu0, sig0), 5), fill = 'cyan4', alpha=0.2) +
stat_function(fun = dnorm, args = c(mu1, sig1), geom = 'area',
xlim = c(-4, qnorm(1-alpha/tail, mu0, sig0)), fill = 'chocolate3', alpha=0.5) +
geom_text(x=-0.4, y=0.18, label=expression(1-alpha), size=10, col="white") +
geom_text(x=2, y=0.018, label=expression(alpha), size=10, col="white") +
geom_text(x=1, y=0.1, label=expression(beta), size=10, col="white") +
geom_text(x=2.5, y=0.1, label=expression(1-beta), size=10, col="black") +
geom_text(x=-1.7, y=0.35, label="H0", size=10, col="black") +
geom_text(x=3.5, y=0.35, label="H1", size=10, col="black") +
labs(y="Densité")
}
PwrPlot()
You can put the colours inside aes() and combined with scale_fill_identity() you can construct a legend.
library(ggplot2)
PwrPlot <- function(mu0=0, mu1=1.9, sig0=1, sig1=1, alpha=0.05, tail=1){
ggplot(data.frame(x = -4:5), aes(x)) +
stat_function(fun = dnorm, args = c(mu0, sig0), geom = 'area',
xlim = c(qnorm(1-alpha/tail, mu0, sig0), 5),
aes(fill = 'red')) +
stat_function(fun = dnorm, args = c(mu0, sig0)) +
stat_function(fun = dnorm, args = c(mu0, sig0), geom = 'area',
xlim = c(-4, qnorm(1-alpha/tail, mu0, sig0)),
aes(fill = 'deepskyblue3')) +
stat_function(fun = dnorm, args = c(mu0, sig0)) +
stat_function(fun = dnorm, args = c(mu1, sig1)) +
stat_function(fun = dnorm, args = c(mu1, sig1), geom = 'area',
xlim = c(qnorm(1-alpha/tail, mu0, sig0), 5),
aes(fill = 'cyan4'), alpha=0.2) +
stat_function(fun = dnorm, args = c(mu1, sig1), geom = 'area',
xlim = c(-4, qnorm(1-alpha/tail, mu0, sig0)),
aes(fill = 'chocolate3'), alpha=0.5) +
scale_fill_identity(
labels = expression(beta, 1-alpha, 1-beta, alpha),
guide = guide_legend()
) +
annotate(
"text", size = 10,
x = c(-0.4, 2, 1, 2.5, -1.7, 3.5),
y = c(0.18, 0.018, 0.1, 0.1, 0.35, 0.35),
label = expression(1-alpha, alpha, beta, 1-beta, "H0", "H1"),
colour = rep(c("white", "black"), each = 3)
) +
labs(y="Densité")
}
PwrPlot()
#> Warning in is.na(x): is.na() applied to non-(list or vector) of type
#> 'expression'
Created on 2021-10-14 by the reprex package (v2.0.1)

label of the rejection and acceptance zone

I am constructing the following graph but the acceptance and rejection labels do not look good and I tried anyway and nothing
p1 <- ggplot(data = data.frame(x = c(0, 4)), aes(x))
p1<-p1+stat_function(fun = dnorm, n = 49, args =list(mean = 2, sd = 3/7),geom = "area",fill="blue2",alpha=0.5,aes(color="aceptacion"))
p1<-p1 +stat_function(fun = dnorm, args = list(mean = 2, sd = 3/7), xlim = c(2.905, 4),geom ="area", fill = "red", alpha = 0.5,aes(color="rechazo"))
p1
How do I correct it?
Try this
mycolor<- c("blue2","red")
myvalues <- c("aceptacion","rechazo")
df <- data.frame(x = c(0, 4))
p1 <- ggplot(data = df, aes(x))
p1 <- p1+stat_function(fun = dnorm, n = 49, args =list(mean = 2, sd = 3/7),xlim = c(0, 2.905) ,geom = "area",fill="blue2",alpha=0.5)
p1 <- p1 +stat_function(fun = dnorm, args = list(mean = 2, sd = 3/7), xlim = c(2.905, 4),geom ="area", fill = "red")
p1 <- p1 + aes(color=myvalues)
p1 <- p1 + scale_color_manual(name="", values=mycolor)
p1 <- p1 + guides(color= guide_legend(override.aes=list(fill=mycolor)))
p1
You get the following output:

Mathematical expression in tick mark labels, ggplot2

I want to make tick mark labels using mathematical expressions.
See the next example:
library(tidyverse)
gl<-30
ggplot(data = data.frame(x = c(-5, 5)), aes(x)) +
stat_function(fun = dt, args = list(df = 30))+ylab("f(t)")+
geom_segment(aes(x=qt(.975,gl),xend=qt(.975,gl),y=0,yend=dt(qt(.975,gl),gl)))+
scale_x_continuous("t", round(c(-5,qt(1-.975,gl),0,qt(.975,gl),5),3), limits=c(-5,5),labels=c("-5.000", "-2.042", "0" ,"list(q[0.95]==0.025)", "5.000"))+
annotate("segment", x = c(2.2), xend = c(3.8),
y = c(0.02), yend = c(.16), colour = "red", size=1, alpha=0.6, arrow=arrow())+
annotate("segment", x = c(-1), xend = c(-3),
y = c(0.02), yend = c(.16), colour = 1, size=1, alpha=0.6, arrow=arrow())+
stat_function(fun = dt, args = list(df = gl),
xlim = c(-5,qt(.975,gl)),
geom = "area",fill="red",alpha=0.5)+
annotate("text", x = c(-3.8,3.8,4), y = c(0.18,0.18,.3),
label = c("1-alpha","alpha/2","list(q[0.95]==0.025)"),parse=T , size=4 , fontface="bold")+
theme_bw()
If line
scale_x_continuous("t", round(c(-5,qt(1-.975,gl),0,qt(.975,gl),5),3), limits=c(-5,5),labels=c("-5.000", "-2.042", "0" ,"list(q[0.95]==0.025)", "5.000"))
Is replaced by
scale_x_continuous("t", round(c(-5,qt(1-.975,gl),0,qt(.975,gl),5),3), limits=c(-5,5),labels=c("-5.000", "-2.042", "0" ,"list(q[0.95]==0.025)", "5.000"),parse=T)
An error is obtained:
Error in scale_x_continuous("t", round(c(-5, qt(1 - 0.975, gl), 0,
qt(0.975, : unused argument (parse = T)
How to achieve mathematical expressions in scale_x_continuous as is achieved in annotate?
You can use plotmath expressions in expression vectors to make this happen.
library(tidyverse)
mf<-55
sdf<-8
weight_lim<-c(30, 110)
xlabels <- expression(
"-5.000",
"-2.042",
"0",
q[0.95]==0.025,
"5.000"
)
ggplot(data = data.frame(weight = weight_lim), aes(weight)) +
stat_function(fun = dnorm, n = 101, args = list(mean = mf, sd = sdf),color=2) +
geom_segment(aes(x=50,xend=50,y=c(0),yend=c(dnorm(50,mf,sdf))),linetype=2,col=2)+
stat_function(fun = dnorm, args = list(mean = mf,sd=sdf),
xlim = c(weight_lim[1],50),
geom = "area",fill="red",alpha=0.5)+
ylab("f(weight)") + scale_x_continuous("t", seq(weight_lim[1],weight_lim[2], length.out =5),
limits=weight_lim,
labels= xlabels) +
theme_bw()
Created on 2020-07-15 by the reprex package (v0.3.0)
xlabels <- c(
~ "-5.000",
~ "-2.042",
~ "0",
~ list(q[0.95]==0.025),
~ "5.000"
)
ggplot(......) + ...... +
scale_x_continuous("t", round(c(-5,qt(1-.975,gl),0,qt(.975,gl),5),3),
limits=c(-5,5),
labels= xlabels)

Resources