-2

I am trying to generate a legend for a line graph I have created using ggplot. From what I have been reading, the legend should be made automatically given I have changed the aesthetics of the graph and included the linetype within the aes function but it is not visible. I have been scouring through answers to this exact question online and have tried many approaches but nothing seems to be working. I think I am missing something quite minor. I tried using scale_linetype_manual but this did not produce a legend. Any help would be appreciated.

    jpeg(filename = "careercurve.jpeg", width = 12, height = 10, units = "cm", res = 1200)
  ggplot() +
    scale_y_continuous(limits = c(0.5,0.8))+
   geom_line(aes(x = Age, y = fwd.preds), data = fwd.predictions, linetype = 1) +
    geom_line(aes(x = Age, y = def.preds), data = def.predictions, linetype = 2) +
    geom_line(aes(x = Age, y = mid.preds), data = mid.predictions, linetype = 3) +
    geom_line(aes(x = Age, y = ruck.preds), data = ruck.predictions, linetype = 4) +
    theme_bw() + theme(panel.border = element_blank(), panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"), axis.text = element_text(colour = "black", size = 8), axis.title = element_text(size = 8), legend.position = "bottom")+
    labs(x = "Age (years)", y = "AFL Player Rank/min (au)") +
    geom_text(aes(x = 35.4, y = 0.535, label = "Fwd"), size = 3) +
    geom_text(aes(x = 35.4, y = 0.50, label = "Def"), size = 3) +
    geom_text(aes(x = 35.4, y = 0.575, label = "Mid"), size = 3) +
    geom_text(aes(x = 35.4, y = 0.67, label = "Ruck"), size = 3)
  dev.off()
Gunasekar
  • 611
  • 1
  • 8
  • 21
Courtney
  • 147
  • 1
  • 1
  • 5
  • ggplot will do more of the work for you (including legends) if you feed it long (aka "tidy") data and map the different aspects of your data to different aesthetics. So instead of specifying the four series of `preds` as you have here, I'd recommend using something like `tidyr::gather(type, value, fwd.preds:ruck:preds)` to make your data long, and then replace the four geom_line calls with one, like `geom_line(aes(x = Age, color = type)...` – Jon Spring Oct 24 '18 at 04:12

2 Answers2

1

The easiest way to work with ggplot2 is if you can get all your data in a single dataframe, with columns to identify any important groups. So in your case, you need to give all the fwd.preds columns in your separate dataframes a common name, and add a new column to identify the group. Then you can combine them and plot, e.g.:

library(dplyr)

# Separate dfs
fwd_df = data.frame(
    Age = rpois(10, 20),
    fwd.preds = rnorm(10)
)
def_df = data.frame(
    Age = rpois(10, 20),
    def.preds = rnorm(10)
)

# Make all the column names the same, add
#   a position column
fwd_df = fwd_df %>%
    mutate(Position = "fwd") %>%
    rename(Pred = fwd.preds)
def_df = def_df %>%
    mutate(Position = "def") %>%
    rename(Pred = def.preds)
# Combine into single df
combined_df = bind_rows(fwd_df, def_df)

ggplot(combined_df, aes(x = Age, y = Pred, linetype = Position)) +
    geom_line()

Note that we can now just include the Position column in aes(), and ggplot handles the legend and different linetypes automatically.

Marius
  • 58,213
  • 16
  • 107
  • 105
0

This is because your linetype is not within the 'aes' brackets but is rather a series of constants. I don't know what your datasets look like, but the simplest solution would probably be to create a column in each dataframe that is the name of the data set.

Then you would have

geom_line(aes(x = Age, y = ..., linetype = df), data = ...) 

However, a better solution, I suspect, would involve combining the data into the one dataframe, even if it's only in a temporary data frame.

Daniel V
  • 1,305
  • 7
  • 23