I have a bar chart that I made in excel using the mtcars dataset but I need to create it in R. I know how to make a stacked chart, but it is possible to add the data table like this below/integrated with the graphic?
Thank you,
I have a bar chart that I made in excel using the mtcars dataset but I need to create it in R. I know how to make a stacked chart, but it is possible to add the data table like this below/integrated with the graphic?
Thank you,
patchwork can be used to combine the two graphs and ggtext can be used for the legend.
library(tidyverse)
library(patchwork)
library(ggtext)
Transform the data. With ggtext we can use markdown in the gear column. We'll use the ■ symbol and colour it.
df <-
mtcars %>%
mutate(
color = case_when(
gear == 5 ~ "#F8766D",
gear == 4 ~ "#00BA38",
gear == 3 ~ "#619CFF",
),
gear = fct_reorder(as_factor(glue::glue("<b style='color:{color}'>■</b> {gear} Gears")), gear),
cyl = paste0(cyl, " Cyl")
) %>%
count(gear, cyl)
p1 <-
ggplot(df, aes(cyl, n, fill = gear)) +
geom_col() +
scale_y_continuous(breaks = seq(from = 0, to = 16, by = 2), lim = c(0, 16)) +
theme_minimal() +
theme(
legend.position = "none",
axis.title.x = element_blank(),
axis.title.y = element_blank(),
panel.grid.minor.x = element_blank(),
panel.grid.major.x = element_blank(),
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_line(colour = "grey")
) +
labs(
title = "Gears and Cylinders - mtcars.csv"
)
p2 <-
df %>%
ggplot(aes(cyl, gear, label = n)) +
geom_text() +
geom_hline(yintercept = c(0.5, 1.5, 2.5), colour='grey') +
theme_void() +
theme(
axis.text.y = element_markdown(),
plot.title = element_blank()
)
Use patchwork to combine it together.
p1 + p2 + plot_layout(ncol = 1, heights = c(7, 2))
I guess you could do something like this:
df <- as.data.frame(table(mtcars$cyl, mtcars$gear))
names(df) <- c("cyl", "gear", "n")
df$ypos <- -2 * as.numeric(df$gear) - 1
df$gear <- factor(df$gear, levels = c(5, 4, 3))
ggplot(df, aes(x = cyl, y = n, fill = gear)) +
geom_col(position = position_stack(), width = 0.5) +
geom_hline(yintercept = c(-4, -6)) +
geom_text(aes(label = n, y = ypos)) +
geom_text(data = data.frame(label = c("4 cyl", "6 cyl", "8 cyl"),
cyl = c("4", "6", "8"), n = -1),
aes(x = cyl, y = n, label = label), inherit.aes = FALSE) +
scale_y_continuous(limits = c(-10, 16), breaks = 0:8 * 2) +
scale_fill_manual(values = c("#ff8021","#5dceb0", "#5fccf3")) +
labs(title = "Gears and Cylinders - mtcars.csv", y = "") +
theme_bw() +
theme(plot.title = element_text(hjust = 0.5, color = "gray50", size = 20),
legend.position = c(0, 0.25),
legend.key.height = unit(1, "cm"),
panel.grid.major.x = element_blank(),
panel.grid.minor.y = element_blank(),
panel.border = element_rect(fill = NA, color = NA),
axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.length.x = unit(0, "mm"))
Another approach would be:
library(ggplot2)
library(dplyr)
library(tidyr)
library(patchwork)
library(gridExtra)
#Data
data("mtcars")
#Code for data process
df <- mtcars %>% mutate(gear=factor(paste(gear,'gears'),
levels=c('5 gears','4 gears','3 gears'),
ordered = T),
cyl=paste(cyl,'Cyl')) %>%
group_by(cyl,gear) %>% summarise(N=n())
#Plot
G1 <- ggplot(df,aes(x=cyl,y=N,fill=gear))+
geom_bar(stat = 'identity')+
theme_bw()+scale_fill_manual(values=c('orange','aquamarine3','cyan3'))+
ggtitle('Gears and cylinders')+
theme(plot.title = element_text(hjust=0.5),
legend.position = 'none')
#Table
T1 <- df %>% pivot_wider(names_from = cyl,values_from=N) %>% replace(is.na(.),0)
#Format
#Theme
my_table_theme <- ttheme_default(core=list(bg_params = list(fill = c('orange','aquamarine3','cyan3'), col=NA)))
#Design
g1 <- gridExtra::tableGrob(T1["gear"], theme=my_table_theme, rows = NULL)
g2 <- gridExtra::tableGrob(T1[,-1], rows = NULL)
g2$widths <- unit(rep(0.25, 3), "npc")
haligned <- gtable_combine(g1,g2, along=1)
Fplot <- G1/haligned
Output: