I am trying to reproduce this figure in R using ggplot:
Unfortunately, I am unable to find a way to get the bars in my R chart to cluster instead of stack, as they do in the original.
Steps taken so far
- I have searched many forums and standard R help pages (i.e., stackoverflow, geeksforgeeks, Applied Epi Handbook, ggplot.tidyverse.org etc.), have consulted with my R literate colleagues and even asked Co-Pilot AI for help (we cannot access Chat GPT at my workplace) and still no answers.
My code so far is this:
scale_factor <- 300
ggplot(fig_1_data, aes(x = year)) +
geom_bar(aes(y = count, fill = "Count"), stat = "identity", position = position_dodge(width = 0.8)) +
geom_bar(aes(y = ytd_count, fill = "YTD Count"), stat = "identity", position = position_dodge(width = 0.8)) +
geom_line(aes(y = annual_rate * 300, color = "Annual Rate"), size = 1) + # Adjust scaling factor as needed
geom_line(aes(y = ytd_rate * 300, color = "YTD Rate"), size = 1) + # Adjust scaling factor as needed
geom_label(aes(y = annual_rate * 300, label = annual_rate, color = "Annual Rate"), vjust = -0.5, fill = "white") +
geom_label(aes(y = ytd_rate * 300, label = ytd_rate, color = "YTD Rate"), vjust = -0.5, fill = "white") +
scale_y_continuous(
name = "Number of notifications",
expand = c(0,0),
limits = c(0, 3000),
breaks = seq(0, 3000, by =500),
sec.axis = sec_axis(~./300, name = "Notification rate per 100,000 population") # Adjust scaling factor as needed
) +
scale_fill_manual(values = c("Count" = basic_fill, "YTD Count" = basic_line)) +
scale_color_manual(values = c("Annual Rate" = "#4C535A", "YTD Rate" = "#A10000")) +
labs(x = "Year", fill = "Legend", color = "Legend") +
theme_minimal() +
theme(
axis.title.y.right = element_text(color = "black"),
axis.text.y.right = element_text(color = "black"),
axis.text.y.left = element_text(color = "black"),
axis.text.x.bottom = element_text (color = "black"),
axis.line.x = element_line(colour = "black", linewidth = 0.2),
axis.line.y.left = element_line(colour = "black", linewidth = 0.2),
axis.line.y.right= element_line(colour = "black", linewidth = 0.2),
panel.background = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank()
)+ # remove buffer zones from x and y axes
scale_x_continuous(expand = c(0,0),
breaks = breaks_width(2))
And this is a sample of the underlying data:
tibble::tribble(
~year, ~count, ~ytd_count, ~annual_rate, ~ytd_rate,
2009, 1554, 1457, 7.2, 6.7,
2010, 1640, 1520, 7.4, 6.9,
2011, 1883, 1744, 8.4, 7.8,
2012, 1823, 1714, 8, 7.5,
2013, 1552, 1433, 6.7, 6.2
)