ggplot geom_line on top of geom_bar
You are close but there are a few things to get you the plot you want:
- To connect observations with
geom_line()
you need to add agroup
aesthetic. So if you just addaes(group = 1)
inside thegeom_line()
call you'll get an actual line. - I strongly reccomend you treat the date as
numeric
instead ofcharacter
. Time is generally continuous so it's best to treat it that way unless you have a good reason for using it as a discrete variable. - There are probably multiple good ways to lump the low
value
countries together. I just usedif_else
. It wouldn't work here because but it's worth knowing aboutforcats::fct_lump_*
if you haven't seen it already for doing something similar in a different setting. - The order the colors appear in the stacked plot (and by deafult in the legend) is based on the levels in the factor supplied. It will default to alphabetical order but you can set it manulaly in a number of ways (although {forcats} has many great tools for this purpose. In this case, to put the
"other"
category at the end you can useforcats::reorder()
and specifyafter = Inf
to push that one level to the end no matter what else you have there. - Finally, to get a second axis properly scaled, you need to provide a transformation factor that you use to divide the axis scale by inside
sec_axis()
and then multiply the data series you want to see on that axis by the same vactor.
library(tidyverse)
# create data with date as numeric
import <- data.frame(country = c("USA", "USA", "EU", "NZ", "EU", "Bulgaria", "Romania", "Serbia"),
date = c(1991, 1992, 1994, 1995, 1991, 1991, 1991, 1991),
value = c(1000, 500, 2000, 1500, 1000, 100, 500, 500))
# lump into 'other' if not in top 3 and move to end
import <- import %>%
mutate(country = if_else(value >= sort(value,decreasing = T)[3],
country,
"other")) %>%
mutate(country = fct_relevel(country, "other", after = Inf))
# create data with date as numeric
production <- data.frame(date = c(1991, 1992, 1994, 1995, 1995),
value = c(50, 45, 40, 39, 38))
# calculate scling factor for second axis
trans_fct <- max(import$value)/max(production$value)
# plot with second axis, scaling data series that appears on that axis
ggplot() +
geom_col(data = import,
mapping = aes(x = date, y = value, fill = country)) +
geom_line(data = production, aes(
x = date,
y = value * trans_fct,
group = 1
)) +
scale_y_continuous(name = "Import",
sec.axis = sec_axis( ~ . / trans_fct, name = "Production"))
Created on 2022-01-17 by the reprex package (v2.0.1)