Reputation: 351
I'm creating a graph that has bars using geom_col, with gem_point (line) to compare performance against a "benchmark." The performance measures belong to different domains, so I used facet_wrap to visually split the domains into groups so it's easier to view. However, because there are different numbers of measures per domain, the bar "heights"/widths are different.
df = data.frame(
measure = c("Measure A","Measure B","Measure C","Measure D","Measure E","Measure F","Measure G"),
domain = c("Efficiency","Efficiency","Satisfaction","Satisfaction", "Satisfaction","Satisfaction","Satisfaction"),
overall = c(56, 78, 19, 87, 45, 51, 19),
company = c(45, 89, 18, 98, 33, 55, 4)
)
ggplot(df %>% mutate(fill = ifelse(overall > company, " Below Overall "," Above Overall ")), aes(measure)) +
geom_col(aes(y=company, fill= fill)) + geom_point(aes(y=overall, color="overall"), size=6, shape=124) + coord_flip() +
scale_color_manual(values=c("grey3"),labels=c("Overall")) + scale_fill_manual(values=c(" Below Overall "="lightpink2"," Above Overall "="lightblue2")) + facet_wrap(~domain, ncol=1, scales="free_y")
I saw from an older question posted about calculating the number of bars per domain, and then multiplying the width by a factor. But I can't figure out how to do that and apply it to my graph.
Upvotes: 2
Views: 3304
Reputation: 78792
I end up needing this quite a bit and have switched to geom_segment()
for many of the traditional bar plots.
library(hrbrthemes)
library(ggplot2)
library(dplyr)
data_frame(
measure = c("Measure A","Measure B","Measure C","Measure D","Measure E","Measure F","Measure G"),
domain = c("Efficiency","Efficiency","Satisfaction","Satisfaction", "Satisfaction","Satisfaction","Satisfaction"),
overall = c(56, 78, 19, 87, 45, 51, 19),
company = c(45, 89, 18, 98, 33, 55, 4)
) %>%
mutate(fill = ifelse(overall > company, " Below Overall "," Above Overall ")) %>%
ggplot() +
geom_segment(aes(x=company, xend=0, y=measure, yend=measure, color=fill), size=4) +
geom_point(aes(x=overall, y=measure, color="Overall"), size=6, shape=124, show.legend = FALSE) +
scale_x_comma() +
scale_color_manual(name=NULL,
values=c(`Overall`="grey3", " Below Overall " = "lightpink2",
" Above Overall " = "lightblue2")) +
facet_wrap(~domain, ncol=1, scales="free_y") +
labs(x="Measure", y=NULL) +
theme_ipsum(grid="X")
Another benefit of this is no need for coord_flip()
.
If you really need the thin, separate Overall
guide, there's a way to do that, too.
UPDATE
Facet ordering and spacing…
library(hrbrthemes)
library(ggplot2)
library(dplyr)
library(grid)
library(gridExtra)
data_frame(
measure = c("Measure A","Measure B","Measure C","Measure D","Measure E","Measure F","Measure G"),
domain = c("Efficiency","Efficiency","Satisfaction","Satisfaction", "Satisfaction","Satisfaction","Satisfaction"),
overall = c(56, 78, 19, 87, 45, 51, 19),
company = c(45, 89, 18, 98, 33, 55, 4)
) %>%
mutate(fill = ifelse(overall > company, " Below Overall "," Above Overall ")) %>%
arrange(desc(measure)) %>%
mutate(measure = factor(measure, levels=unique(measure))) %>%
ggplot() +
geom_segment(aes(x=company, xend=0, y=measure, yend=measure, color=fill), size=4) +
geom_point(aes(x=overall, y=measure, color="Overall"), size=6, shape=124, show.legend = FALSE) +
scale_x_comma() +
scale_color_manual(name=NULL,
values=c(`Overall`="grey3", " Below Overall " = "lightpink2",
" Above Overall " = "lightblue2")) +
facet_wrap(~domain, ncol=1, scales="free_y") +
labs(x="Measure", y=NULL) +
theme_ipsum(grid="X") -> gg
gb <- ggplot_build(gg)
gt <- ggplot_gtable(gb)
gt$heights[[7]] <- unit(2/5, "cm") # top panel has 2 out of 5 factors vs 5 out of 5 in the bottom one
grid.newpage() ;
grid.draw(gt)
Upvotes: 2
Reputation: 19716
Perhaps using facet_grid
with space = "free"
would be satisfactory:
ggplot(df %>% mutate(fill = ifelse(overall > company, " Below Overall "," Above Overall ")), aes(measure)) +
geom_col(aes(y=company, fill= fill)) +
geom_point(aes(y=overall, color="overall"), size=6, shape=124) +
scale_color_manual(values=c("grey3"),labels=c("Overall")) +
scale_fill_manual(values=c(" Below Overall "="lightpink2"," Above Overall "="lightblue2")) +
facet_grid(domain~., scales="free", space = "free") +
coord_flip()
Upvotes: 6