Reputation: 282
I have an insert dataset
df <- structure(list(Cluster = c("Cluster1", "Cluster1", "Cluster1",
"Cluster1", "Cluster1", "Cluster1", "Cluster2", "Cluster2", "Cluster2",
"Cluster2", "Cluster2", "Cluster2", "Cluster3", "Cluster3", "Cluster3",
"Cluster3", "Cluster3", "Cluster3", "Cluster4", "Cluster4", "Cluster4",
"Cluster4", "Cluster4", "Cluster4", "Cluster5", "Cluster5", "Cluster5",
"Cluster5", "Cluster5", "Cluster5", "Cluster6", "Cluster6", "Cluster6",
"Cluster6", "Cluster6", "Cluster6", "Cluster7", "Cluster7", "Cluster7",
"Cluster7", "Cluster7", "Cluster7", "Cluster8", "Cluster8", "Cluster8",
"Cluster8", "Cluster8", "Cluster8"), Level = c("Associate", "Director",
"Entry level", "Executive", "Intership", "Mid-Senior Level",
"Associate", "Director", "Entry level", "Executive", "Intership",
"Mid-Senior Level", "Associate", "Director", "Entry level", "Executive",
"Intership", "Mid-Senior Level", "Associate", "Director", "Entry level",
"Executive", "Intership", "Mid-Senior Level", "Associate", "Director",
"Entry level", "Executive", "Intership", "Mid-Senior Level",
"Associate", "Director", "Entry level", "Executive", "Intership",
"Mid-Senior Level", "Associate", "Director", "Entry level", "Executive",
"Intership", "Mid-Senior Level", "Associate", "Director", "Entry level",
"Executive", "Intership", "Mid-Senior Level"), value = c("30%",
"7%", "18%", "5%", "3%", "37%", "30%", "9%", "21%", "2%", "5%",
"32%", "31%", "5%", "32%", "1%", "4%", "26%", "36%", "3%", "29%",
"1%", "2%", "29%", "33%", "4%", "36%", "0%", "6%", "22%", "32%",
"5%", "29%", "2%", "4%", "29%", "25%", "7%", "23%", "2%", "2%",
"41%", "24%", "2%", "18%", "2%", "3%", "50%")), class = "data.frame", row.names = c(NA,
-48L))
Is it possible to use it to create plot like this?
A plot with a table down from every bar
Upvotes: 4
Views: 1284
Reputation: 4487
Reference to @teunbrand recommendation I work on it a bit with some little hack to achieve something similar but not perfectly match what OP share.
library(dplyr) # for maninpulate data
library(ggplot2) # for ploting
library(magrittr) # for `%<>%` syntax
library(scales) # for labeling
library(tidyr) # for manipulate data
library(patchwork) # for align plot/tables
# generate a table to be displayed at bottom of graph with Cluster as column
table_display <- df %>% pivot_wider(names_from = Cluster, values_from = value)
# Conver value into actual numeric values in percentages point
df %<>% mutate(value = as.numeric(gsub("%", "", value)) / 100)
# Create an empty ticks to align the table later.
empty_tick <- df %>% filter(Cluster == "Cluster1") %>%
mutate(value = 0, Cluster = "")
# Generate the plot with the empty tick
p1 <- ggplot() +
geom_bar(data = bind_rows(empty_tick, df), aes(x = Cluster, y = value,
group = Level, fill = Level),
stat = "identity", position = "dodge") +
# here the empty tick is the first tick which would align with Level
# column of the table at bottom
scale_x_discrete(breaks = c("", unique(df$Cluster))) +
# label Y-Axis
scale_y_continuous(labels = percent, expand = c(0, 0)) +
# remove X/Y labels
xlab(NULL) + ylab(NULL) +
# Using a default whi
theme_bw()
# Extract legend for the main plot
legend <- get_legend(p1)
p1 <- p1 + theme(legend.position = "none")
# Generate table grob with no header rows/cols
p2 <- gridExtra::tableGrob(table_display, rows = NULL, cols = NULL)
# Set widths/heights to 'fill whatever space I have'
p2$widths <- unit(rep(1, ncol(p2)), "null")
p2$heights <- unit(rep(1, nrow(p2)), "null")
# Format table as plot
p3 <- ggplot() +
annotation_custom(p2)
# Patchwork magic
p1 + legend + p3 + plot_layout(ncol = 2, widths = c(4, 1))
Here is the output plot
Upvotes: 4