I need to make a bar plot by country and sources of income. As I have 13 income components by each single country, I'm using colors and patterns to make a clearer distinction. Here a subsample of the data:
structure(list(country = c("Austria", "Austria", "Austria", "Austria",
"Austria", "Austria", "Austria", "Austria", "Austria", "Austria",
"Austria", "Austria", "Belgium", "Belgium", "Belgium", "Belgium",
"Belgium", "Belgium", "Belgium", "Belgium", "Belgium", "Belgium",
"Belgium", "Belgium", "Germany"), `relative contributions` = c(1.12873709201813,
0.190666541457176, 0.0881932526826859, -0.0167537834495306, -0.0258312318474054,
0.215001374483109, -0.00148478976916522, -0.000572826422285289,
-0.0133617669343948, -0.00855048839002848, -0.00286591215990484,
-0.55317747592926, 1.43853068351746, 0.12194737046957, 0.0775384828448296,
-0.00403465563431382, -0.0196540541946888, -0.0183424148708582,
-0.0311897918581963, -0.00196828553453088, -0.00494809495285153,
-0.0225886180996895, -0.000150939886225387, -0.535139620304108,
1.23838818073273), component = c("Employee wages", "Self-employment",
"Capital", "Private transfers", "Unemployment", "Old-age survivors",
"Sick disability", "Education", "Social exclusion allowances",
"Family allowances", "Housing allowances", "Taxes", "Employee wages",
"Self-employment", "Capital", "Private transfers", "Unemployment",
"Old-age survivors", "Sick disability", "Education", "Social exclusion allowances",
"Family allowances", "Housing allowances", "Taxes", "Employee wages"
)), row.names = c(NA, -25L), class = c("tbl_df", "tbl", "data.frame"
))
Up to now, I was able to produce the following plot:
pat <- c('bricks', 'fishscales', 'verticalsaw', 'crosshatch', 'checkboard', 'octagons', 'verticalbrics', 'vertical', 'right45', 'hs_horizontal', 'horizontalsaw', 'hs_cross', 'hexagons')
ggplot(relative)
geom_bar_pattern(aes(x=country, y=`relative contributions`, fill=factor(component), pattern_type=factor(component)), stat="identity", position="stack", width = 0.6, pattern='magick', pattern_scale = 0.5, colour="black")
scale_fill_manual(name="Income components", values = mycolors) scale_pattern_type_discrete(choices = pat, guide = 'none')
scale_y_continuous(limits = c(-1,2), breaks = scales::pretty_breaks(n = 7))
theme_bw()
theme(axis.text.x = element_text(angle=45, hjust=1, vjust=1)) xlab("") ylab("") theme(plot.title = element_text(hjust = 0.5)) `
Which results in the following figure:
However, the legend does not report the pattern. If I offset guide="none" I will have two legends, but is there a way to have a unique legend (as in the current version) reporting both the colors and the patterns?
Many thanks for the help!
CodePudding user response:
Remove guide="none"
to show the patterns in the legend but add name="Income components"
to scale_pattern_xxx
so that the guides get merged. Otherwise the scales have different names and you end up with two separate legends.
Note: I switched to scale_fill_discrete
as mycolors
was not provided.
library(ggplot2)
library(ggpattern)
ggplot(relative)
geom_bar_pattern(aes(x = country, y = `relative contributions`, fill = factor(component), pattern_type = factor(component)), stat = "identity", position = "stack", width = 0.6, pattern = "magick",
pattern_scale = 0.5, colour = "black")
scale_fill_discrete(name = "Income components")
scale_pattern_type_discrete(name = "Income components", choices = pat)
scale_y_continuous(limits = c(-1, 2), breaks = scales::pretty_breaks(n = 7))
theme_bw()
theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1))
xlab("")
ylab("")
theme(plot.title = element_text(hjust = 0.5))