I created this bar chart I am not happy with:
I do not want to have the relevant labels shown in the x-axis when an author (Me/Them/You) does not have any values.
For instance, the facet "Them" has no value with regards to the x-axis label "Raceway". This should be completely omitted.
How to achieve that?
This is my dataframe (df
):
structure(list(author = c("Me", "Me", "Them", "Them", "Them",
"Them", "Them", "You", "You"), display_name = c("Raceway", "Pulverized coal-fired boiler",
"Hollow fiber membrane", "Permeation", "Residence time distribution",
"Fluidization", "Rotary kiln", "Rotary kiln", "Raceway"), n = c(4,
2, 4, 4, 3, 2, 2, 3, 3), sum_score = c(3.69998413, 1.4438111,
2.5820569, 2.32903219, 1.90571574, 1.86841225, 1.42931327, 2.8,
2.2)), row.names = c(NA, -9L), class = c("tbl_df", "tbl", "data.frame"
))
This is the code to factor the keyword (column display_name
) by group (author
), based on this:
df <- transform(df, category2 = factor(paste(author, display_name)))
df <- transform(df, category2 = reorder(category2, rank(sum_score)))
This is the ggplot code:
ggplot(df, aes(x = category2, y = sum_score, fill = author)) +
geom_bar(stat = "identity") +
facet_wrap(. ~ author, scales = "free_x", nrow = 3) +
scale_x_discrete(labels = df$display_name, breaks = df$category2) +
scale_y_continuous(limits = c(0, max(DF3$sum_score))) +
scale_fill_manual("legend", values = c("You" = "#006699", "Me" = "orange", "Them" = "#720016")) +
ylab("") +
xlab("") +
theme_minimal() +
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = "none"
) +
coord_flip()
Thanks for your help!
To get rid of the unused levels you could add scales="free_y"
instead of "free_x"
. Additionally I would suggest to switch to facet_grid
as it allows bars of equal width using space="free_y"
.
Note: I switched x and y to get rid of coord_flip
. Perhaps that was also the reason why you confused "free_x" and "free_y".
library(ggplot2)
ggplot(df, aes(y = category2, x = sum_score, fill = author)) +
geom_bar(stat = "identity") +
facet_grid(author ~ ., scales = "free_y", space = "free_y") +
scale_y_discrete(labels = df$display_name, breaks = df$category2) +
scale_x_continuous(limits = c(0, NA)) +
scale_fill_manual("legend",
values = c("You" = "#006699", "Me" = "orange", "Them" = "#720016")
) +
ylab("") +
xlab("") +
theme_minimal() +
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = "none"
)
And if you still want the facet labels on top you could use ggforce::facet_col
in which case we have to fix the axis limits as you did in your original code:
library(ggplot2)
ggplot(df, aes(y = category2, x = sum_score, fill = author)) +
geom_bar(stat = "identity") +
ggforce::facet_col(author ~ .,
scales = "free", space = "free"
) +
scale_y_discrete(labels = df$display_name, breaks = df$category2) +
scale_x_continuous(limits = c(0, max(df$sum_score))) +
scale_fill_manual("legend",
values = c("You" = "#006699", "Me" = "orange", "Them" = "#720016")
) +
ylab("") +
xlab("") +
theme_minimal() +
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
legend.position = "none"
)