简体   繁体   中英

Shading region between vertical and diagonal lines in ggplot

I am trying to use ggplot to shade the region between the vertical line and the diagonal line as shown below. Is there a way to do this?

df <- data.frame(x=c(1,-1), y=c(1,-1))

ggplot(df, aes(x, y)) +
  geom_point() +
  geom_abline(slope=-1) +
  geom_vline(xintercept = 0)

在此处输入图像描述

It is a bit tricky, but if you know the coordinates of the area (Inf), you can use them to fill the shades using geom_polygon like this:

library(ggplot2)
df <- data.frame(x=c(1,-1), y=c(1,-1))
upper_area <- data.frame(x=c(-Inf,0,0),y=c(Inf,Inf,0))
down_area <- data.frame(x=c(0,0,Inf),y=c(0,-Inf,-Inf))

ggplot(df, aes(x, y)) +
  geom_point() +
  geom_abline(slope=-1) +
  geom_vline(xintercept = 0) +
  geom_polygon(aes(x=x, y=y), data=upper_area, fill="red") +
  geom_polygon(aes(x=x, y=y), data=down_area, fill="blue")

Created on 2022-07-15 by the reprex package (v2.0.1)

old answer

It is a bit tricky, but if you know the coordinates of the area, you can use them to fill the shades using geom_polygon like this:

library(ggplot2)
df <- data.frame(x=c(1,-1), y=c(1,-1))
upper_area <- data.frame(x=c(-1,0,0),y=c(1,1,0))
down_area <- data.frame(x=c(0,0,1),y=c(0,-1,-1))

ggplot(df, aes(x, y)) +
  geom_point() +
  geom_abline(slope=-1) +
  geom_vline(xintercept = 0) +
  geom_polygon(aes(x=x, y=y), data=upper_area, fill="red") +
  geom_polygon(aes(x=x, y=y), data=down_area, fill="blue")

Created on 2022-07-15 by the reprex package (v2.0.1)

One option would be to use annotate with geom="ribbon" :

df <- data.frame(x=c(1,-1), y=c(1,-1))

library(ggplot2)

ggplot(df, aes(x, y)) +
  geom_point() +
  # 1.1 = 1 + default expansion of 5 % of the data range, i.e. .05 * 2 (= 1  - (-1))
  annotate(geom="ribbon", x = c(-Inf, 0), ymin = c(1.1, 0), ymax = Inf, fill = "grey45") +
  annotate(geom="ribbon", x = c(0, Inf), ymin = -Inf, ymax = c(0, -1.1), fill = "grey45") +
  geom_vline(xintercept = 0) +
  geom_abline(slope=-1) +
  coord_cartesian(xlim = c(-1, 1), ylim = c(-1, 1))

For a more robust example with a flexible slope and intercept

library(ggplot2)
df <- data.frame(x=c(1,-1), y=c(1,-1))

slope = -0.5
intercept = 0.5

ggplot(df, aes(x, y)) +
  geom_point() +
  geom_abline(slope = slope) +
  geom_vline(xintercept = intercept) +
  annotate(geom="ribbon", x = c(min(df$x), intercept), ymin = c(min(df$x) * slope, slope * intercept), ymax = Inf, fill = "red") +
  annotate(geom="ribbon", x = c(intercept, Inf), ymin = -Inf, ymax = c(slope * intercept, max(df$x) * slope), fill = "blue") +
  scale_x_continuous(expand = c(0,0))

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM