I have found it challenging to create a treemap using ggplot, and
Using the workaround in this blog, but adding an additional hierarchy and wanted to change the labeling is where the problem comes in.
# Create the plot in ggplot using geom_rect
# Get underlying data created from running treemap
tm_plot_data <- tree_p$tm %>%
mutate(x1 = x0 w,
y1 = y0 h) %>%
mutate(x = (x0 x1)/2,
y = (y0 y1)/2) %>%
mutate(
primary_group = case_when(
level == 1 ~ 1.5,
level == 2 ~ 0.75,
TRUE ~ 0.5
)
)
# Plot
ggplot(tm_plot_data, aes(xmin = x0, ymin = y0, xmax = x1, ymax = y1))
# add fill and borders for groups and subgroups
geom_rect(aes(fill = color, size = primary_group),
show.legend = FALSE,
color = "black",
alpha = 0.3
)
scale_fill_identity()
# set thicker lines for group borders
scale_size(range = range(tm_plot_data$primary_group))
# add labels
ggfittext::geom_fit_text(aes(label = my_segment), color = "white", min.size = 1)
ggfittext::geom_fit_text(aes(label = my_class), color = "blue", min.size = 1)
ggfittext::geom_fit_text(aes(label = my_type), color = "red", min.size = 1)
# options
scale_x_continuous(expand = c(0, 0))
scale_y_continuous(expand = c(0, 0))
theme_void()
So the question I have is there a way to create the labeling like treemap? Specifically, seg_a
, seg_b
, and seg_c
should only appear once, centered over the area of their respective segments. I'd also like to move the labels so that they do not overlap
Thanks for any help and suggestions!
CodePudding user response:
The issue is that you use your full dataset tm_plot_data
to add the labels. Hence, for each upper level you you get multiple labels. To solve this issue aggregate your datasets and pass these datasets as data
to ggfittext::geom_fit_text
. To deal with overlapping labels you could e.g. use the place
argument of ggfittext::geom_fit_text
to move the class labels to the bottom left and the type labels to the topright.
library(tidyverse)
library(treemap)
set.seed(123)
tm_seg <- tm_plot_data %>%
group_by(my_segment) %>%
summarise(x0 = min(x0), y0 = min(y0), y1 = max(y1), x1 = max(x1)) %>%
ungroup()
tm_class <- tm_plot_data %>%
group_by(my_segment, my_class) %>%
summarise(x0 = min(x0), y0 = min(y0), y1 = max(y1), x1 = max(x1)) %>%
ungroup()
tm_type <- tm_plot_data %>%
group_by(my_segment, my_class, my_type) %>%
summarise(x0 = min(x0), y0 = min(y0), y1 = max(y1), x1 = max(x1)) %>%
ungroup()
# Plot
ggplot(tm_plot_data, aes(xmin = x0, ymin = y0, xmax = x1, ymax = y1))
# add fill and borders for groups and subgroups
geom_rect(aes(fill = color, size = primary_group),
show.legend = FALSE,
color = "black",
alpha = 0.3
)
scale_fill_identity()
# set thicker lines for group borders
scale_size(range = range(tm_plot_data$primary_group))
# add labels
ggfittext::geom_fit_text(data = tm_seg, aes(label = my_segment), color = "white", min.size = 4)
ggfittext::geom_fit_text(data = tm_class, aes(label = my_class), color = "blue", min.size = 1, place = "bottomleft")
ggfittext::geom_fit_text(data = tm_type, aes(label = my_type), color = "red", min.size = 1, place = "topright")
# options
scale_x_continuous(expand = c(0, 0))
scale_y_continuous(expand = c(0, 0))
theme_void()
#> Warning: Removed 3 rows containing missing values (geom_fit_text).
#> Warning: Removed 12 rows containing missing values (geom_fit_text).