Is there a way to make a stacked barplot with continuous breaks and labels? Transforming my dataframe from a "wider version" to a "longer version" allowed me to make a stacked barplot, but now my labels are misaligned (CYR 2009 should be directly above WYR 2010, etc..), which I fixed, but an empty barplot has appeared to the far right above where 2022 was because of this change.
I've tried to only displaying the years <= 2021 and simply shift the 2nd x-axis to the left in order to line-up the two labels, but that doesn't seem to do anything about the "empty" barplot space.
My original data form:
>dput(prop)
structure(list(WYR = c(2010, 2011, 2012, 2013, 2014, 2015, 2016,
2017, 2018, 2019, 2020, 2021, 2022), CYR = c(2009, 2010, 2011,
2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021),
prop_zero = c(0.745762711864407, 0.888888888888889, 0.739130434782609,
0.842857142857143, 0.958333333333333, 0.915492957746479,
0.929577464788732, 0.75, 0.76056338028169, 0.720588235294118,
0.785714285714286, 0.6875, 0.833333333333333), prop_nonzero = c(0.254237288135593,
0.111111111111111, 0.260869565217391, 0.157142857142857,
0.0416666666666667, 0.0845070422535211, 0.0704225352112676,
0.25, 0.23943661971831, 0.279411764705882, 0.214285714285714,
0.3125, 0.166666666666667)), class = "data.frame", row.names = c(NA,
-13L))
"Longer" version:
>dput(prop)
structure(list(WYR = c(2010, 2010, 2011, 2011, 2012, 2012, 2013,
2013, 2014, 2014, 2015, 2015, 2016, 2016, 2017, 2017, 2018, 2018,
2019, 2019, 2020, 2020, 2021, 2021, 2022, 2022), CYR = c(2009,
2009, 2010, 2010, 2011, 2011, 2012, 2012, 2013, 2013, 2014, 2014,
2015, 2015, 2016, 2016, 2017, 2017, 2018, 2018, 2019, 2019, 2020,
2020, 2021, 2021), class = c("prop_zero", "prop_nonzero", "prop_zero",
"prop_nonzero", "prop_zero", "prop_nonzero", "prop_zero", "prop_nonzero",
"prop_zero", "prop_nonzero", "prop_zero", "prop_nonzero", "prop_zero",
"prop_nonzero", "prop_zero", "prop_nonzero", "prop_zero", "prop_nonzero",
"prop_zero", "prop_nonzero", "prop_zero", "prop_nonzero", "prop_zero",
"prop_nonzero", "prop_zero", "prop_nonzero"), proportions = c(0.745762711864407,
0.254237288135593, 0.888888888888889, 0.111111111111111, 0.739130434782609,
0.260869565217391, 0.842857142857143, 0.157142857142857, 0.958333333333333,
0.0416666666666667, 0.915492957746479, 0.0845070422535211, 0.929577464788732,
0.0704225352112676, 0.75, 0.25, 0.76056338028169, 0.23943661971831,
0.720588235294118, 0.279411764705882, 0.785714285714286, 0.214285714285714,
0.6875, 0.3125, 0.833333333333333, 0.166666666666667)), row.names = c(NA,
-26L), class = c("tbl_df", "tbl", "data.frame"))
Breaks and labels:
years <- seq(2009,2021,1)
labs <- seq(2009,2021,by=1)
Plot:
ggplot(prop[which(prop$CYR<=2021),], aes(x=CYR, y=proportions, fill=class))
geom_bar(position="fill", stat="identity")
scale_y_continuous(limits = c(0, 1.0), expand = expansion(mult = c(0, 0.05)))
scale_x_continuous(breaks= years, labels = ~ rep("", length(.x)))
# CYR labels
annotate(geom = "text",
x = prop$CYR,
y = -Inf,
label = labs,
size = 8.8 / .pt,
vjust = 2.5)
# WYR labels
annotate(geom = "text",
x = prop$WYR,
y = -Inf,
label = prop$WYR,
size = 8.8 / .pt,
vjust = 4,
hjust = 3.4,
color = "grey")
# CYR title
annotate(geom = "text",
x = -Inf,
y = -Inf,
label = c("CYR"),
vjust = 2.5, hjust = 1,
size = 8.8 / .pt)
# WYR title
annotate(geom = "text",
x = -Inf,
y = -Inf,
label = c("WYR"),
vjust = 4, hjust = 1,
size = 8.8 / .pt,
color = "grey")
coord_cartesian(clip = "off")
theme(axis.title.x = element_blank())
# Make extra space between axis ticks and axis title
theme(axis.text.x.bottom = element_text(margin = margin(t = 8.8, b = 8.8)),
axis.text.x = element_text(size = 10, color = "grey"),
axis.title.x = element_blank(),
axis.text.y = element_text(size = 10),
axis.title.y = element_text(margin = margin(t = 0, r = 10, b = 0, l = 0), size = 14),
axis.ticks = element_line(colour = "black", size = 1),
panel.border = element_rect(fill = NA, color = "black", size = 1),
legend.position = "none")
labs(y = "Proportion")
CodePudding user response:
The issue is that you use x = prop$WYR
as the x coordinates for your WYR labels which adds an empty bar for year 2022. Instead use x = prop$CYR
and remove the - IMHO - unnecessary hjust
to align both rows of labels.
library(ggplot2)
years <- seq(2009, 2021)
ggplot(prop[which(prop$CYR <= 2021), ], aes(x = CYR, y = proportions, fill = class))
geom_bar(position = "fill", stat = "identity")
scale_y_continuous(limits = c(0, 1.0), expand = expansion(mult = c(0, 0.05)))
scale_x_continuous(breaks = years, labels = ~ rep("", length(.x)))
# CYR labels
annotate(
geom = "text",
x = prop$CYR,
y = -Inf,
label = prop$CYR,
size = 8.8 / .pt,
vjust = 2.5
)
# WYR labels
annotate(
geom = "text",
x = prop$CYR,
y = -Inf,
label = prop$WYR,
size = 8.8 / .pt,
vjust = 4,
color = "grey"
)
# CYR title
annotate(
geom = "text",
x = -Inf,
y = -Inf,
label = c("CYR"),
vjust = 2.5, hjust = 1,
size = 8.8 / .pt
)
# WYR title
annotate(
geom = "text",
x = -Inf,
y = -Inf,
label = c("WYR"),
vjust = 4, hjust = 1,
size = 8.8 / .pt,
color = "grey"
)
coord_cartesian(clip = "off")
theme(axis.title.x = element_blank())
# Make extra space between axis ticks and axis title
theme(
axis.text.x.bottom = element_text(margin = margin(t = 8.8, b = 8.8)),
axis.text.x = element_text(size = 10, color = "grey"),
axis.title.x = element_blank(),
axis.text.y = element_text(size = 10),
axis.title.y = element_text(margin = margin(t = 0, r = 10, b = 0, l = 0), size = 14),
axis.ticks = element_line(colour = "black", size = 1),
panel.border = element_rect(fill = NA, color = "black", size = 1),
legend.position = "none"
)
labs(y = "Proportion")