I would like to create a shaded area in color blue between the two dotted lines (-0.5 and 0.5), tried with geom_polygon() but didn't work.
How can this be done in the best possible way?
model <- lm(Sepal.Width ~ Petal.Length, data = iris)
ggplot(data.frame(x = seq(model$residuals), y = model$residuals)) +
geom_point(aes(x, y)) +
geom_hline(yintercept = 0, linetype = "dashed") +
geom_hline(yintercept = 0.5, linetype = "dotted") +
geom_hline(yintercept = -0.5, linetype = "dotted") +
labs(x = "Index", y = "Residuals",
title = paste("Residuals of", format(model$call)))
You can use geom_ribbon
ggplot(data.frame(x = seq(model$residuals), y = model$residuals)) +
geom_point(aes(x, y)) +
geom_ribbon(aes(x, ymin = -0.5, ymax = 0.5), alpha = 0.3, fill = 'steelblue')+
geom_hline(yintercept = 0, linetype = "dashed") +
geom_hline(yintercept = 0.5, linetype = "dotted") +
geom_hline(yintercept = -0.5, linetype = "dotted") +
labs(x = "Index", y = "Residuals",
title = paste("Residuals of", format(model$call)))
With annotate:
annotate("rect", xmin = -Inf, xmax = Inf, ymin = -0.5, ymax = 0.5, alpha = .2, fill = "blue")
Output:
ggplot(data.frame(x = seq(model$residuals), y = model$residuals)) +
geom_point(aes(x, y)) +
geom_hline(yintercept = 0, linetype = "dashed") +
geom_hline(yintercept = c(-0.5, 0.5), linetype = "dotted") +
annotate("rect", xmin = -Inf, xmax = Inf, ymin = -0.5, ymax = 0.5, alpha = .2, fill = "blue") +
labs(x = "Index", y = "Residuals",
title = paste("Residuals of", format(model$call)))
Related
I want to create a plot with geom_line() and geom_rect(). For both I would like to create a legend, but I does not work. How can both be combined? As you can see in the attached picture, my legend is messed up: Colours and shapes are not correctly displayed.
graph= data.frame(seq(as.Date("2004/01/01"), as.Date("2022/01/01"), by="month"),rnorm(217,mean=1,sd=2),rnorm(217,mean=1,sd=2),rnorm(217,mean=1,sd=2))
colnames(graph) = c("Datum","VPI","VPIF","VPIE")
plot1 = ggplot(graph, aes(x = graph$Datum)) +
geom_line(aes(y = graph$VPI, colour = "black"), size = 0.8) +
geom_line(aes(y = graph$VPIF, colour = "red"), size = 0.8) +
geom_line(aes(y = graph$VPIE, colour = "snow4"), size = 0.8) +
geom_rect(aes(xmin = graph$Datum[49], xmax = graph$Datum[72], ymin = 125, ymax = 130,fill="cyan") ,alpha = 0.5)+
geom_rect(aes(xmin = graph$Datum[84], xmax = graph$Datum[120], ymin = 125, ymax = 130,fill="darkolivegreen"), alpha = 0.5)+
geom_rect(aes(xmin = graph$Datum[195], xmax = graph$Datum[217], ymin = 125, ymax = 130,fill="blueviolet"), alpha = 0.5)+
scale_fill_manual(name=NULL,values=c("black","red","snow4","cyan","darkolivegreen","blueviolet"), labels=c("VPI","VPI Lebensmittel","VPI Energie","Weltfinanzkrise","Euro-/Schuldenkrise","Coronakrise"),aesthetics = c("colour","fill")) +
theme_bw() +
theme(legend.position = "bottom",
axis.text.x = element_text(angle = 90)) +
labs(title = "Verbraucherpreisindex: Gesamt, Lebensmittel, Energie", subtitle = "2015=100",
y = "Prozent",
x = "Jahre")
plot1
Transform the data from wide to long. Here I used pivot_longer from the tidyverse package. But you can also use melt or reshape.
library(tidyverse)
data_rect <- tibble(xmin = graph$Datum[c(49,84,195)],
xmax = graph$Datum[c(72,120,217)],
ymin = 50,
ymax=53,
gr = c("1", "2", "3"))
graph %>%
pivot_longer(-1) %>%
ggplot(aes(Datum, value)) +
geom_line(aes(color = name)) +
geom_rect(data=data_rect, inherit.aes = F, aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, fill=gr))
Something like this?
graph %>%
pivot_longer(
-Datum
) %>%
ggplot(aes(x=Datum, y = value)) +
geom_line(aes(color = name)) +
scale_color_manual(name = NULL, values = c("black", "red", "snow4"))+
geom_rect(aes(xmin = graph$Datum[49], xmax = graph$Datum[72], ymin = 125, ymax = 130,fill="cyan") ,alpha = 0.5)+
geom_rect(aes(xmin = graph$Datum[84], xmax = graph$Datum[120], ymin = 125, ymax = 130,fill="darkolivegreen"), alpha = 0.5)+
geom_rect(aes(xmin = graph$Datum[195], xmax = graph$Datum[217], ymin = 125, ymax = 130,fill="blueviolet"), alpha = 0.5)+
scale_fill_manual(name = NULL, values = c("cyan", "darkolivegreen", "blueviolet"))
theme_bw() +
theme(legend.position = "bottom",
axis.text.x = element_text(angle = 90)) +
labs(title = "Verbraucherpreisindex: Gesamt, Lebensmittel, Energie", subtitle = "2015=100",
y = "Prozent",
x = "Jahre")
Is there a way to create a figure similar to the one below without having any data on this?
You could do something like this. You could add another geom_curve and a couple of geom_vlines.
library(tidyverse)
ggplot() +
geom_abline() +
geom_curve(aes(x = 0, y = 0, xend = 1, yend = 1), curvature = -0.4) +
annotate("text", x = 0.5, y = 0.5, label = "Line of Equality", angle = 35, vjust = 2) +
labs(x = "Individuals Neighbourhoods\nAcross Space", y = "Scoioeconomic Position") +
theme_minimal() +
theme(axis.text = element_blank())
Created on 2022-04-27 by the reprex package (v2.0.1)
For the arrows you can use this code: arrow = arrow(length = unit(0.5, "cm")) in a geom_segment. It is a bit tricky without any numbers, but maybe you want something like this:
library(ggplot2)
ggplot() +
geom_abline(slope = 1) +
geom_curve(aes(x = 0, y = 0, xend = 1, yend = 1), curvature = -0.4) +
geom_curve(aes(x = 0, y = 1, xend = 1, yend = 0.1), curvature = 0.4, linetype = "dashed") +
geom_segment(aes(x=0.9,y=0.98,xend=0.9,yend=0.12), arrow = arrow(length = unit(0.5, "cm"))) +
geom_segment(aes(x=0.02,y=0.85,xend=0.02,yend=0.23), arrow = arrow(length = unit(0.5, "cm"))) +
annotate("text", x = 0.5, y = 0.5, label = "Line of Equality", angle = 45, vjust = 2) +
annotate("text", x = 0.25, y = 0.75, label = "Income (etc.)", angle = 45, vjust = 2) +
annotate("text", x = 1.2, y = 0.1, label = "Corresponding\nExposure", angle = 0) +
labs(x = "Individuals Neighbourhoods\nAcross Space", y = "Scoioeconomic Position") +
scale_x_continuous(limits = c(0, 1.3)) +
theme_minimal() +
theme(axis.text = element_blank())
Output:
I can't see, to figure out how to add labels to this plot:
ggplot(input_cleaned, aes(x =DAYS_TO_FA, y = fct_rev(DATE_TEXT), group = fct_rev(DATE_TEXT))) +
geom_density_ridges2(stat="binline", bins = 75, scale = 0.95, draw_baseline = FALSE) +
labs(title = 'Monthly Plots of Time to First Nose Pickin', y='Month Tracked', x = 'Days to First Pickin Action') +
theme(plot.title = element_text(hjust = 0.5), plot.subtitle = element_text(hjust = 0.5)) +
scale_x_continuous(breaks=seq(0,130,5)) +
geom_segment(aes(x=50, xend = 50, y=1,yend=5),
linetype = "dashed", size = 1.5,
color = "black") +
geom_segment(aes(x=75, xend = 75, y=5,yend=30),
linetype = "dashed", size = 1.5,
color = "black")
which produces:
I have tried this:
ggplot(input_cleaned, aes(x =DAYS_TO_FA, y = fct_rev(DATE_TEXT), group = fct_rev(DATE_TEXT))) +
geom_density_ridges2(stat="binline", bins = 75, scale = 0.95, draw_baseline = FALSE) +
geom_text(stat = "bin",
aes(y = fct_rev(input_cleaned$DATE_TEXT) + 0.95*(..count../max(..count..)), label = ifelse(..count..>0, ..count.., "")),
vjust = 1.4, size = 3, color = "white", binwidth = 1) +
labs(title = 'Monthly Plots of Time to First Nose Pickin', y='Month Tracked', x = 'Days to First Pickin Action') +
theme(plot.title = element_text(hjust = 0.5), plot.subtitle = element_text(hjust = 0.5)) +
scale_x_continuous(breaks=seq(0,130,5)) +
geom_segment(aes(x=50, xend = 50, y=1,yend=5),
linetype = "dashed", size = 1.5,
color = "black") +
geom_segment(aes(x=75, xend = 75, y=5,yend=30),
linetype = "dashed", size = 1.5,
color = "black")
based on the example found here:
Visualization of Groups of Poisson random samples using ggridges
but I can't get it to work. Nothing changes.
I know it may not be a good idea for this graph, but I am interested in seeing how it looks and more or less learning how to apply it.
I want to highlight the area between a vertical line and a normal distributed function. I know how it works with discrete values, but the stat_function confuses me. The code looks something like this:
library(ggplot2)
n1 <- 5
ggplot(data.frame(x = c(-2, 2)), aes(x)) +
stat_function(fun = dnorm, args = list(sd = 1/sqrt(n1))) +
geom_vline(xintercept = 0.5, linetype = "dashed", color = "red", size = 1) +
geom_vline(xintercept = -0.5, linetype = "dashed", color = "red", size = 1) +
ylim(c(0, 1.5)) +
theme_light() +
geom_rect(aes(xmin = 0.5, xmax = Inf, ymax = Inf, ymin = 0), fill = "grey", alpha = .3)
I know I need to change ymax to the values of x > 0.5. The question is how?
EDIT:
I looked into the question which is supposed to be the same as mine. When I rewrite the code the way they did, the highlighting works but it doesn't give me a proper normal distribution anymore, as you can see here:
library(dplyr)
set.seed(123)
range <- seq(from = -2, to = 2, by = .01)
norm <- rnorm(range, sd = 1 / sqrt(n1))
df <- data_frame(x = density(norm)$x, y = density(norm)$y)
ggplot(data_frame(values = norm)) +
stat_density(aes(x = values), geom = "line") +
geom_vline(xintercept = 0.5, linetype = "dashed", color = "red", size = 1) +
geom_vline(xintercept = -0.5, linetype = "dashed", color = "red", size = 1) +
ylim(c(0, 1.5)) +
theme_light() +
geom_ribbon(data = filter(df, x > 0.5),
aes(x = x, ymax = y), ymin = 0, fill = "red", alpha = .5)
When I stick with stat_function and use geom_ribbon with subsetting as proposed in the very same question, it highlights buggy, as you can see here:
ggplot(data_frame(x = c(-2, 2)), aes(x)) +
stat_function(fun = dnorm, args = list(sd = 1/sqrt(n1))) +
geom_vline(xintercept = 0.5, linetype = "dashed", color = "red", size = 1) +
geom_vline(xintercept = -0.5, linetype = "dashed", color = "red", size = 1) +
ylim(c(0, 1.5)) +
theme_light() +
geom_ribbon(data = filter(df, x > 0.5),
aes(x = x, ymax = y), ymin = 0, fill = "red", alpha = .5)
Not satisfying yet.
Here is an approach:
library(ggplot2)
n1 <- 5
ggplot(data.frame(x = c(-2, 2)), aes(x)) +
stat_function(fun = dnorm, geom = "area", fill = "grey", alpha = 0.3, args = list(sd = 1/sqrt(n1)), xlim = c(-0.5,0.5)) +
stat_function(fun = dnorm, args = list(sd = 1/sqrt(n1))) +
geom_vline(xintercept = 0.5, linetype = "dashed", color = "red", size = 1) +
geom_vline(xintercept = -0.5, linetype = "dashed", color = "red", size = 1) +
ylim(c(0, 1.5)) +
theme_light()
in stat_function one can define different geom, just pick the ones that suits your needs.
I'm interested in ways to only include panel grid lines right near the ribbon--I can do this manually, in a trivial example
library(ggplot2)
d1 <- data.frame(x = seq(0, 1, length.out = 200))
d1$y1 <- -3*(d1$x-.5)^2 + 1
d1$y2 <- -3*(d1$x-.5)^2 + 2
ggplot(d1) +
geom_ribbon(aes(x, ymin = y1, ymax = y2),
alpha = .25) +
geom_ribbon(aes(x, ymax = y1),
ymin = .25,
fill = "white") +
geom_ribbon(aes(x, ymin = y2),
ymax = 2,
fill = "white") +
scale_y_continuous(limits = c(.25, 2.0),
expand = c(0, 0))+
scale_x_continuous(limits = c(0, 1),
expand = c(0, 0))+
theme_bw() +
theme(panel.grid = element_line(linetype = 1, color = "black"))
is there some less hacky way to have a transparent mask for these gridlines, so they only appear underneath a ribbon?
If gridlines the same color as the background are acceptable, you can remove the actual gridlines, then use geom_hline() and geom_vline() to make your own "gridlines" that will show on ribbons but be invisible against the background
d1$y3 <- d1$x + 0.3
d1$y4 <- d1$x + 0.4
ggplot(d1) +
geom_ribbon(aes(x, ymin = y1, ymax = y2), alpha = 0.25) +
geom_ribbon(aes(x, ymin = y3, ymax = y4), alpha = 0.25, fill = "blue") +
# use geom_vline and geom_hline to plot "gridlines" on top of ribbons
geom_hline(yintercept = seq(0, 2, by = 0.25), colour = "white") +
geom_vline(xintercept = seq(0, 1, by = 0.25), colour = "white") +
scale_y_continuous(limits = c(.25, 2.0), expand = c(0, 0)) +
scale_x_continuous(limits = c(0, 1), expand = c(0, 0)) +
theme_bw() +
theme(panel.grid.minor = element_blank(), # remove actual gridlines
panel.grid.major = element_blank())
produces this:
This is still a workaround, and will only make gridlines that match the background color, but it is easy to use with a variety of plots, such as the situation you mentioned with multiple ribbons (I've added a second ribbon to demonstrate that this will work)