Manfredo Manfredo - 2 months ago 10
R Question

R: Object not found with ggplot

I am trying to add legend names to a ggplot but I always get an "object not found error".

mycol = pft$colour
myname = pft$name
#mycol "#E5E503" "#9FFF8C" "#44CC29" "#137300" "#B2B224" "#0066CC" "#99CCFF" "#00407F" "#FF999B" "#E5171A" "#990003" "#A38FCC" "#7F40FF" "#A1E5CF" "#6B998A" "#F2F291" "#BF60A7" "#404040"
#myname "C4 grass" "Early tropical" "Mid tropical" "Late tropical" "Temperate C3 Grass" "North Pine" "South Pine" "Late conifer" "Early hardwood" "Mid hardwood" "Late hardwood" "C3 crop" "C3 pasture" "C4 crop" "C4 pasture" "C3 grass" "Lianas" "Total"
test_data_long = melt(szpft[[vnam]][,ndbh+1,],
varnames = c("year","mpft"), na.rm = T)
ggplot(data=test_data_long,aes(x=year,y=value, colour = mycol[mpft])) +
geom_line(aes(group = mpft)) +
scale_colour_identity(guide = "legend") +
scale_fill_continuous(name="PFT", labels = myname[mpft])


test_data_long
is a
data.frame
that looks like this.

year mpft value
20 2004 2 2.294562
21 2005 2 2.415901
22 2006 2 2.532214
23 2007 2 2.649968
24 2008 2 2.760934
25 2009 2 2.849097
26 2010 2 2.967846
27 2011 2 3.102287
28 2012 2 3.244338
29 2013 2 3.386014
30 2014 2 3.528662
31 2015 2 3.675095
32 2016 2 3.828054
33 2017 2 3.976928
34 2018 2 4.133859
35 2019 2 4.305039
36 2020 2 4.488999
37 2021 2 4.673952
38 2022 2 4.861845
39 2004 3 4.518262
40 2005 3 4.668800
41 2006 3 4.821924
42 2007 3 4.973597


I would like to use the
mpft
column as an index to define grouping, color, title ecc.

mycol
and
myname
are vectors that contain colours (hex) and names corresponding to the different
mpft
lines to plot. The exact error I get is

Error in check_breaks_labels(breaks, labels) : object 'mpft' not found


Removing the last line of the script produce the next figure, so the problem lies in the last line. Why is
mpft
recognized before and not after?



EDIT

To be clearer,

mycol = pft$colour
myname = pft$name
test_data_long = melt(szpft[[vnam]][,ndbh+1,],
varnames = c("year","mpft"), na.rm = T)
ggplot(data=test_data_long,aes(x=year,y=value, colour = mycol[mpft])) +
geom_line(aes(group = mpft)) +
scale_colour_identity(guide = "legend")


produces the graph in figure and gives no error.

EDIT

I'll provide a simplified, reproducible example of what I want to achieve here.

mycol = c("#A38FCC","#7F40FF")
mynam = c("random_line1", "random_line2")
set.seed(123)
df=data.frame(month = month.abb,
mpft = c(rep(1,6),rep(2,6)),
ran = runif(12,0.,10.))


That produces a dataframe with
month
,
mpft
, and
ran
value. I want the
ggplot
to have
month
on the x-axis and
ran
on the y-axis. Furthermore I want the points to be plotted with
mycol[1]
colour ("#A38FCC" color) and the legend to display
mynam[1]
as title (random_line1 as title) if
mpft = 1
.

Answer

This is similar to the other answer but without needless dplyr mumbo-jumbo and pointing out some important details. The point is that if you want manual colors, you should use a manual color scale.

mycol = c("#A38FCC","#7F40FF")
mynam = c("random_line1", "random_line2")
set.seed(123)
df=data.frame(
              #month needs to be an ordered factor to get correct order in the plot
              #an unordered factor would be ordered alphabetically by ggplot2
              month = ordered(month.abb, levels = month.abb), 
              mpft  = c(rep(1,6),rep(2,6)), 
              ran = runif(12,0.,10.))

library(ggplot2)

ggplot(df, aes(x=month,y=ran, 
               colour = factor(mpft) #you want a discrete color scale
               )) +
  geom_line(aes(group = mpft), size = 1) +
  scale_colour_manual(name = "mynam",
                      #always pass named character vectors here to ensure correct mapping
                      values = setNames(mycol, unique(df$mpft)), 
                      labels = setNames(mynam, unique(df$mpft))) 

enter image description here