Reputation: 55
I have the following data frame:
df <- structure(list(Source = structure(c(1L, 1L, 2L, 2L, 1L, 1L, 2L,2L, 1L, 1L, 2L, 2L), .Label = c("Nutrition", "Supplements"), class = "factor"),Gender = c("Female", "Male", "Female", "Male", "Female","Male", "Female", "Male", "Female", "Male", "Female", "Male"), vitamins = c("Carbohydrates", "Carbohydrates", "Carbohydrates","Carbohydrates", "Free sugars", "Free sugars", "Free sugars","Free sugars", "Dietary fibre", "Dietary fibre", "Dietary fibre","Dietary fibre"), percentage = c(103.257255625661, 103.435668737283,12.1783865511905, 10.3397081952058, 26.9383952366656, 14.6831075438958,66.1535947328921, 62.5632737468906, 161.653065420191, 205.648132846479,50.7043993619127, 48.5061463560061)), row.names = c(NA, -12L), class = c("tbl_df", "tbl", "data.frame"))
I would like to create this chart without facets, just with fill, color and linetype. I'm trying to figure it out for 2 hours and I don't know how to do it.
The order is very important. The first should be a group of "vitamins" with the highest percentage. Is there a way to decrease the gap between barcharts within groups? And is there a way to i.e. add gender as a second legend, where male category would be bar with stripes?
Your help is much appreciated.
Upvotes: 0
Views: 200
Reputation: 42544
I have tried to reproduce the given chart as close as possible with the code below:
library(ggplot2)
ggplot(df) +
aes(x = factor(Gender, levels = c("Male", "Female")),
y = percentage,
fill = factor(Source, levels = c("Supplements", "Nutrition"))) +
geom_col(width = 0.5) +
facet_wrap(~ factor(vitamins, levels = c("Dietary fibre", "Carbohydrates", "Free sugars")),
strip.position = "bottom") +
ylab(NULL) + xlab(NULL) +
scale_fill_manual(name = NULL, values = c(Supplements = "#C0504D", Nutrition = "#4F81BD")) +
scale_y_continuous(limits = c(0, 300), breaks = seq(0, 300, 50), minor_breaks = NULL, expand = expand_scale()) +
theme_minimal() +
theme(strip.placement = "outside", panel.grid.major.x = element_blank())
Note that facet_wrap()
is still being used together with the positioning parameter strip.position = "bottom"
and the theme modification strip.placement = "outside"
which tells ggplot to place the facet label below the x axis label.
Also note that the bars within each group are positioned closer together as requested by the OP.
theme_minimal()
removes most of the usual decorations including the rectangles around the facet panels. Also note that factor levels are given explicitely to force data to appear in the expected order.
df <- structure(list(Source = structure(c(1L, 1L, 2L, 2L, 1L, 1L, 2L,
2L, 1L, 1L, 2L, 2L), .Label = c("Nutrition", "Supplements"), class = "factor"),
Gender = c("Female", "Male", "Female", "Male", "Female",
"Male", "Female", "Male", "Female", "Male", "Female", "Male"
), vitamins = c("Carbohydrates", "Carbohydrates", "Carbohydrates",
"Carbohydrates", "Free sugars", "Free sugars", "Free sugars",
"Free sugars", "Dietary fibre", "Dietary fibre", "Dietary fibre",
"Dietary fibre"), percentage = c(103.257255625661, 103.435668737283,
12.1783865511905, 10.3397081952058, 26.9383952366656, 14.6831075438958,
66.1535947328921, 62.5632737468906, 161.653065420191, 205.648132846479,
50.7043993619127, 48.5061463560061)), row.names = c(NA, -12L
), class = c("tbl_df", "tbl", "data.frame"))
Upvotes: 5