I would like to first draw a bunch of areas and then have the resulting overall area be displayed with the same single alpha value. So instead of this:
library(tidyverse)
dat <- tribble(
~xmin, ~xmax, ~ymin, ~ymax,
10, 30, 10, 30,
20, 40, 20, 40,
15, 35, 15, 25,
10, 15, 35, 40
)
ggplot() +
geom_rect(data = dat,
aes(
xmin = xmin,
xmax = xmax,
ymin = ymin,
ymax = ymax
),
alpha = 0.5)
I would want to have this as my outcome:
Created on 2022-07-26 by the reprex package (v2.0.1)
I feel like the answer to my question may be similar to the one in this thread but I don't fully understand it and thus am not sure. Also note that I used geom_rect()
for the reprex, but ultimately I want this to work for ggforce::geom_circle()
.
Quinten's first answer, which points to scale_alpha(range = ..., limits = ...)
, is unfortunately not answering my question, since it can apparently only result in non-transparent areas.
Quinten's updated answer is a workaround I could accept for the reprex above. However, as I've mentioned above, too, I want this to work for ggforce::geom_circle()
. Unfortunately, I guess I have to be more specific now and create another reprex. (Sorry)
library(ggforce)
#> Lade nötiges Paket: ggplot2
dat <- data.frame(
x = c(1, 1.3, 1.6),
y = c(1, 1, 1),
circle = c("yes", "yes", "no")
)
ggplot() +
coord_equal() +
theme_classic() +
geom_circle(
data = subset(dat, circle == "yes"),
aes(x0 = x, y0 = y, r = 0.5, alpha = circle),
fill = "grey",
color = NA,
show.legend = TRUE
) +
geom_point(
data = dat,
aes(x, y, color = circle)
) +
scale_color_manual(
values = c("yes" = "blue", "no" = "red")
) +
scale_alpha_manual(
values = c("yes" = 0.25, "no" = 0)
)
Created on 2022-08-17 by the reprex package (v2.0.1)
ggblend
I also saw ggblend
few moments ago, but wasn't sure it would fix your problem, luckily it does! You can do two things:
Code:
#remotes::install_github("mjskay/ggblend")
library(ggblend)
library(ggforce)
# reprex 1 ----------------------------------------------------------------
library(tidyverse)
dat <- tribble(
~xmin, ~xmax, ~ymin, ~ymax,
10, 30, 10, 30,
20, 40, 20, 40,
15, 35, 15, 25,
10, 15, 35, 40
)
p1 <- ggplot() +
geom_rect(data = dat,
aes(
xmin = xmin,
xmax = xmax,
ymin = ymin,
ymax = ymax
),
alpha = 0.3) %>% blend("source")
p1
# reprex 2 ----------------------------------------------------------------
dat <- data.frame(
x = c(1, 1.3, 1.6),
y = c(1, 1, 1),
circle = c("yes", "yes", "no")
)
p2 <- ggplot() +
coord_equal() +
theme_classic() +
geom_circle(
data = subset(dat, circle == "yes"),
aes(x0 = x, y0 = y, r = 0.5, alpha = circle),
fill = "grey",
color = NA,
show.legend = TRUE
) %>% blend("source") +
geom_point(
data = dat,
aes(x, y, color = circle)
) +
scale_color_manual(
values = c("yes" = "blue", "no" = "red")
) +
scale_alpha_manual(
values = c("yes" = 0.25, "no" = 0)
)
p2
#ggsave(plot = p2, "p2.pdf", device = cairo_pdf)
png
with type = "cairo"
like this:library(ggblend)
library(ggforce)
# reprex 1 ----------------------------------------------------------------
library(tidyverse)
dat <- tribble(
~xmin, ~xmax, ~ymin, ~ymax,
10, 30, 10, 30,
20, 40, 20, 40,
15, 35, 15, 25,
10, 15, 35, 40
)
p1 <- ggplot() +
geom_rect(data = dat,
aes(
xmin = xmin,
xmax = xmax,
ymin = ymin,
ymax = ymax
),
alpha = 0.3) %>% blend("source")
#> Warning: Your graphics device, "quartz_off_screen", reports that blend = "source" is not supported.
#> - If the blending output IS NOT as expected (e.g. geoms are not being
#> drawn), then you must switch to a graphics device that supports
#> blending, like png(type = "cairo"), svg(), or cairo_pdf().
#> - If the blending output IS as expected despite this warning, this is
#> likely a bug *in the graphics device*. Unfortunately, several
#> graphics do not correctly report their capabilities. You may wish to
#> a report a bug to the authors of the graphics device. In the mean
#> time, you can disable this warning via options(ggblend.check_blend =
#> FALSE).
#> - For more information, see the Supported Devices section of
#> help('blend').
png(filename = "plot1.png", type = "cairo")
# Output in your own folder:
p1
dev.off()
#ggsave(plot = p1, "p1.pdf", device = cairo_pdf)
# reprex 2 ----------------------------------------------------------------
dat <- data.frame(
x = c(1, 1.3, 1.6),
y = c(1, 1, 1),
circle = c("yes", "yes", "no")
)
p2 <- ggplot() +
coord_equal() +
theme_classic() +
geom_circle(
data = subset(dat, circle == "yes"),
aes(x0 = x, y0 = y, r = 0.5, alpha = circle),
fill = "grey",
color = NA,
show.legend = TRUE
) %>% blend("source") +
geom_point(
data = dat,
aes(x, y, color = circle)
) +
scale_color_manual(
values = c("yes" = "blue", "no" = "red")
) +
scale_alpha_manual(
values = c("yes" = 0.25, "no" = 0)
)
#> Warning: Your graphics device, "quartz_off_screen", reports that blend = "source" is not supported.
#> - If the blending output IS NOT as expected (e.g. geoms are not being
#> drawn), then you must switch to a graphics device that supports
#> blending, like png(type = "cairo"), svg(), or cairo_pdf().
#> - If the blending output IS as expected despite this warning, this is
#> likely a bug *in the graphics device*. Unfortunately, several
#> graphics do not correctly report their capabilities. You may wish to
#> a report a bug to the authors of the graphics device. In the mean
#> time, you can disable this warning via options(ggblend.check_blend =
#> FALSE).
#> - For more information, see the Supported Devices section of
#> help('blend').
png(filename = "plot2.png", type = "cairo")
# Output in your folder
p2
dev.off()
#ggsave(plot = p2, "p2.pdf", device = cairo_pdf)
Created on 2022-08-17 with reprex v2.0.2
Update
What you could do is take the UNION of the areas using st_union
from the sf
package so you get one area instead of overlapping areas like this:
library(tidyverse)
library(sf)
dat <- tribble(
~xmin, ~xmax, ~ymin, ~ymax,
10, 30, 10, 30,
20, 40, 20, 40,
15, 35, 15, 25,
10, 15, 35, 40
)
area1 <- dat %>%
slice(1) %>%
as_vector() %>%
st_bbox() %>%
st_as_sfc()
area2 <- dat %>%
slice(2) %>%
as_vector() %>%
st_bbox() %>%
st_as_sfc()
area3 <- dat %>%
slice(3) %>%
as_vector() %>%
st_bbox() %>%
st_as_sfc()
area4 <- dat %>%
slice(4) %>%
as_vector() %>%
st_bbox() %>%
st_as_sfc()
all_areas <- st_union(area1, area2) %>%
st_union(area3) %>%
st_union(area4)
ggplot(all_areas) +
geom_sf(alpha = 0.5, fill = "grey", colour = "grey") +
theme(legend.position = "none")
ggplot(all_areas) +
geom_sf(alpha = 0.8, fill = "grey", colour = "grey") +
theme(legend.position = "none")
Created on 2022-08-17 by the reprex package (v2.0.1)
First answer
Maybe you want this where you can use a scale_alpha
with range
and limits
to keep the area in the same alpha
like this:
library(tidyverse)
dat <- tribble(
~xmin, ~xmax, ~ymin, ~ymax,
10, 30, 10, 30,
20, 40, 20, 40,
15, 35, 15, 25,
10, 15, 35, 40
)
ggplot() +
geom_rect(data = dat,
aes(
xmin = xmin,
xmax = xmax,
ymin = ymin,
ymax = ymax,
alpha = 0.5
)) +
scale_alpha(range = c(0, 1), limits = c(0, 0.5)) +
theme(legend.position = "none")
Created on 2022-07-26 by the reprex package (v2.0.1)