Search code examples
rggplot2

Slope chart but getting ylim() warning


I'm trying to build my first slope chart, modeled after an online guide.

df1 <- dplyr::data_frame('tests' = c("2023","2024"),
                         'Pre-season Avg.' = c(42.35,51.38),
                         'Post-season Avg.' = c(90.4,86.56))
colnames(df1) <- c("tests", "Pre-season Avg.", "Post-season Avg.")
left_label <- paste(df1$'tests', df1$'Pre-season Avg.')
right_label <- paste(df1$'tests', df1$'Post-season Avg.')
df1$class <- ifelse((df1$'Post-season Avg.' - df1$'Pre-season Avg.') < 0, "red", "dodgerblue")
plot <- ggplot(df1) +
  geom_segment(aes(x=1, xend=2, y="Pre-season Avg.", yend="Post-season Avg.", col=class), size=0.75,
  show.legend=F) +
  geom_vline(xintercept=1, linetype="dashed", size=0.1) +
  geom_vline(xintercept=2, linetype="dashed", size=0.1) +
  scale_color_manual(labels = c("Up","Down"),
                     values=c("red", "dodgerblue")) +
  labs(x="", y="Scores by Average") +
  xlim(0.5,2.5) + ylim(0, (1.1*(max(df1$'Pre-season Avg.', df1$'Post-season Avg.'))))     

plot <- plot + geom_text(label=left_label, y=df1$'Pre-season Avg.', x=rep(1, NROW(
  df1)), hjust=1.1, size=3.5)
plot <- plot + geom_text(label=right_label, y=df1$'Post-season Avg.', x=rep(2, NROW(
  df1)), hjust=-0.1, size=3.5)
plot <- plot + geom_text(label="Pre-season", x=1, y=1.1*(max(df1$'Pre-season Avg.', df1$'Post-season Avg.')),
  hjust=1.2, size=5)
plot <- plot + geom_text(label="Post-season", x=2, y=1.1*(max(df1$'Pre-season Avg.', df1$'Post-season Avg.')),
  hjust=-0.1, size=5)

plot + theme(panel.background = element_blank(), 
          panel.grid = element_blank(),
          axis.ticks = element_blank(),
          axis.text.x = element_blank(),
          panel.border = element_blank(),
          plot.margin = unit(c(1,2,1,2), "cm"))
plot

Both df1$'Pre-season Avg.' and df1$'Pre-season Avg.' are double, yet I'm getting the warning:

Error in `ylim()`:
! Discrete values supplied to continuous scale.
ℹ Example values: "Pre-season Avg." and "Pre-season Avg."

But I don't understand why I'm getting the warning, since I (at least think) am using continuous values on a continuous scale. I'm clearly making a mistake, but I cannot identify what it is.


Solution

  • You define aes(y="Pre-season Avg."). This is interpreted as the string "Pre-season Avg." and a string is discrete. Either use a more programming-friendly variable name, then use e.g. aes(y = pre_season_avg) or use the backtick like aes(y=`Pre-season Avg.`)

    Overall, there are quite a few things I would do differently, to make the plot a bit easier to build:

    # first reformat the data to long format
    df1 |> 
      pivot_longer(2:3, names_to = 'season', values_to = 'average') |> 
      mutate(season = str_remove(season, ' Avg.')) |> 
      # define overall aesthetics
      ggplot(aes(season, average, group = tests)) +
      # we only need one call to each geom now:
      geom_line(aes(color = class)) +
      geom_vline(xintercept = c(1, 2), linetype = "dashed", size = 0.1) +
      geom_text(aes(label = paste(tests, average)), hjust = 'outward', size = 3.5) +
      # identity scale keeps the values as in your data.frame
      scale_color_identity() +
      scale_x_discrete(limits = c('Pre-season', 'Post-season')) +
      ylim(0, NA) + # NA keeps the current upper limit
      labs(x = NULL, y = "Scores by Average") +
      theme_minimal()
    

    enter image description here