I have a ggplot
issue where I'm trying to make line plots with a very minimal look. I've gotten rid of the legend in favor of text labels at the right side of each line. It might not be so noticeable if the labels weren't so long, but I'd like it better if the gridlines stopped at the maximum x-value (in this case, at the year 2015).
library(tidyverse)
df <- structure(list(industry = c("Accommodation & Food Services", "Construction", "Health Care & Social Asst.", "Retail Trade",
"Accommodation & Food Services", "Construction", "Health Care & Social Asst.", "Retail Trade"),
year = c(2002L, 2002L, 2002L, 2002L, 2015L, 2015L, 2015L, 2015L),
value = c(6.977, 5.264, 17.065, 14.528, 8.032, 4.648, 20.547, 12.568)),
class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -8L),
.Names = c("industry", "year", "value"))
ggplot(df, aes(x = year, y = value, color = industry)) +
geom_line() +
geom_text(aes(label = industry), data = . %>% filter(year == max(year)), size = 3, hjust = 0, nudge_x = 0.1) +
scale_x_continuous(expand = expand_scale(mult = c(0.05, 0.85)), breaks = c(min(df$year), max(df$year)), name = NULL) +
scale_y_continuous(limits = c(0, NA), name = "Value (thousands)") +
theme_minimal() +
theme(legend.position = "none",
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank())
I'd like to avoid the grob-hacking done in this answer because I have several plots and want to put them together quickly.
The solution I've come up with so far is to create pseudo-gridlines by making a geom_segment
with dummy data at regular y-values that starts at the earliest year and ends at the latest one. This works okay, because I have an idea of what y-breaks I want and can set scale_y_continuous
to match geom_segment
.
break_df <- tibble(x1 = 2002, x2 = 2015, y = seq(0, 20, by = 5))
ggplot(df, aes(x = year, y = value, color = industry)) +
geom_segment(aes(x = x1, xend = x2, y = y, yend = y), data = break_df, inherit.aes = F, size = 0.4, color = "gray85") +
geom_line() +
geom_text(aes(label = industry), data = . %>% filter(year == max(year)), size = 3, hjust = 0, nudge_x = 0.1) +
scale_x_continuous(expand = expand_scale(mult = c(0.05, 0.85)), breaks = c(min(df$year), max(df$year)), name = NULL) +
scale_y_continuous(limits = c(0, NA), name = "Value (thousands)", breaks = break_df$y) +
theme_minimal() +
theme(legend.position = "none",
panel.grid = element_blank())
Created on 2018-05-24 by the reprex package (v0.2.0).
What I'm wondering is how ggplot
calculates breaks, and if there's a function it uses that I could harness for this? Like if there's some internal calculation for the breaks that I could feed into both geom_segment
and scale_y_continuous
, so they'd match without me setting up a separate data frame of break information.
Alternatively, maybe this is a silly method and there's a better way to get the gridlines I want. I'm thinking there also might be a way to do this with a trans
function, like building a trans_new()
, but I don't know how to go about that.
Thanks in advance!