I have stacked a data frame which shows value
s per id
across group
s:
df <- tibble::tibble(id = c(LETTERS[1:6], LETTERS[1:5]),
value = c(paste0("V", 1:6), paste0("V", 1:5)),
group = c(rep("group_1", 6), rep("group_2", 5)))
df
#> # A tibble: 11 x 3
#> id value group
#> <chr> <chr> <chr>
#> 1 A V1 group_1
#> 2 B V2 group_1
#> 3 C V3 group_1
#> 4 D V4 group_1
#> 5 E V5 group_1
#> 6 F V6 group_1
#> 7 A V1 group_2
#> 8 B V2 group_2
#> 9 C V3 group_2
#> 10 D V4 group_2
#> 11 E V5 group_2
I want to create a heatmap showing the "availability" of each value
(x) for each id
(y) across group
s (fill):
ggplot(df, aes(x = id, y = value, fill = group))
geom_tile()
The problem is that the fill
overlaps: All I can see is that F/V6 is only in group_1
(and not in group_2
). However, for IDs A to E, values V1 to V5 are available in both groups, and thus the color of group_2
is on top of group_1
, making it look like they are only available in group_2
.
If I use facet_wrap()
, the availability is more obvious:
ggplot(df, aes(x = id, y = value, fill = group))
geom_tile()
facet_wrap("group")
However, in my real setting, the heatmap is very large so it is difficult to compare which values are available in which group.
Is it possible to split each tile in half if the value is available in both groups and keep it full if it is only present in one group? So in the first plot above, the blue tiles would be split in half (showing both blue and red), and the red tile would remain as is.
CodePudding user response:
One option would be to use position="dodge"
:
library(ggplot2)
ggplot(df, aes(x = id, y = value, fill = group))
geom_tile(position = "dodge")
CodePudding user response:
If you want triangles, think you'll probably need to do it manually using some wrangling and geom_polygon
, something like:
library(ggplot2)
df <- tibble::tibble(x = c(LETTERS[1:6], LETTERS[1:5]),
y = c(paste0("V", 1:6), paste0("V", 1:5)),
group = c(rep("group_1", 6), rep("group_2", 5)))
df1 <- df[!duplicated(interaction(df$x, df$y)),]
df2 <- df[duplicated(interaction(df$x, df$y)),]
df2 <- df[rep(seq(nrow(df)), each = 3),]
df2$x1 <- as.numeric(as.factor(df2$x))
df2$y1 <- as.numeric(as.factor(df2$y))
df2$x1 <- df2$x1 c(-0.5, 0.5, 0.5)
df2$y1 <- df2$y1 c(-0.5, -0.5, 0.5)
df2$z <- rep(seq(nrow(df2)/3), each = 3)
ggplot(df1, aes(x = x, y = y, fill = group))
geom_tile()
geom_polygon(data = df2, aes(x = x1, y = y1, group = z))
Created on 2022-02-16 by the reprex package (v2.0.1)