Setting colors in ggplot2 aes

According to ggplot2 Quick Reference: scale | Software and Programmer Efficiency Research Group , the following code should produce a graph with green points, lines, & error bars, all with pink outlines:

Preformatted text

ggplot(BxTC, aes(x = Backlight, y = Mean, group = TargetColor)) +
geom_line(show.legend = FALSE, aes(color = "pink", fill = "green", size = 2.4)) +
geom_point(show.legend = FALSE, aes(color = "pink", fill = "green", size = 6)) +
geom_errorbar(show.legend = FALSE, aes(color = "pink", fill = "green", ymin = Mean - FLSD, ymax = Mean + FLSD, width = 6, size = 2.1)) +
scale_x_continuous(breaks = seq(450, 750, 50)) +
scale_y_continuous(breaks = seq(20, 120, 20)) +
xlab("Backlight (cd/m2)") +
ylab("Score")

But this the the figure I get:

I expected setting the fill and outline colors to be simple, so I'm baffled by my output.

If you want to set an aesthetic to a constant value, that should be done outside of the aes() function. The aes() function is for mapping data values to aesthetics.
I don't think the default line and points have a fill aesthetic; they only have color.

gplot(BxTC, aes(x = Backlight, y = Mean, group = TargetColor)) +
geom_line(show.legend = FALSE, color = "pink", fill = "green", size = 2.4) +
geom_point(show.legend = FALSE, color = "pink", fill = "green", size = 6) +
1 Like

Thank you! Your reply has gotten me close to understanding not only how to control graphing colors, but the sizes of the geoms, as well.

There's at least one more thing I'm missing, though. I believe the code below should produce a chart with red, green, and yellow lines, points, and error bars with black outlining. Instead, I get "! object 'TargetColor' not found".

Preformatted text
ggplot(BxTC, aes(x = Backlight, y = Mean, group = TargetColor)) +
geom_line(show.legend = FALSE, size = 2.4, color = "black", fill = TargetColor) +
geom_point(show.legend = FALSE, size = 6, color = "black", fill = TargetColor) +
geom_errorbar(show.legend = FALSE, ymin = Mean - FLSD, ymax = Mean + FLSD, width = 6, size = 2.1) +
scale_color_manual(values = c("WxRED" = "firebrick1", "WxGREEN" = "green3", "WxYELLOW" = "gold")) +
scale_x_continuous(breaks = seq(450, 750, 50)) +
scale_y_continuous(breaks = seq(20, 120, 20)) +
xlab("Backlight (cd/m2)") +
ylab("Score")

PS - Putting 'exists("TargetColor")'before the ggplot call produces no output. I still get the "not found" error, but neither TRUE nor FALSE appear before it.

For your code to work, TargetColor should be a column in the data frame BxTC. Is it? What is the output of

str(BxTC)
1 Like

Yes, it is -- see below. TargetColor is also a Factor -- that's probably relevant. BxTC is created by:

BxTC = ezStats(weather_summary_df, dv = .(Score), wid = .(SubjectID), within = .(Backlight, TargetColor))

str(BxTC) output:


## 'data.frame':    18 obs. of  6 variables:
##  $ Backlight  : num  450 450 450 500 500 500 550 550 550 600 ...
##  $ TargetColor: Factor w/ 3 levels "WxGREEN","WxRED",..: 1 2 3 1 2 3 1 2 3 1 ...
##  $ N          : num  36 36 36 36 36 36 36 36 36 36 ...
##  $ Mean       : num  25.8 68.1 66.5 28 88.4 ...
##  $ SD         : num  30 28.5 30.6 31 16.9 ...
##  $ FLSD       : num  9.24 9.24 9.24 9.24 9.24 ...

In these lines, fill = TargetColor is outside of an aes() call, so for ggplot you seem to be refering to an object called TargetColor. Only aes() will search in the columns of the data frame, so you should rather write:

ggplot(BxTC, aes(x = Backlight, y = Mean, group = TargetColor, fill = TargetColor)) +
geom_line(show.legend = FALSE, size = 2.4, color = "black") +
geom_point(show.legend = FALSE, size = 6, color = "black") +
...

Also in that case, the presence of fill will automatically group by TargetColor, so you can just use:

ggplot(BxTC, aes(x = Backlight, y = Mean, fill = TargetColor)) +
geom_line(show.legend = FALSE, size = 2.4, color = "black") +
geom_point(show.legend = FALSE, size = 6, color = "black") +
...
1 Like

I believe I tried that possibility before. Now, I get !object 'Mean' not found, followed by

Backtrace:

  1. ggplot2::geom_errorbar(...)
ggplot(BxTC, aes(x = Backlight, y = Mean, fill = TargetColor)) +
  geom_line(show.legend = FALSE, size = 2.4, color = "black") +
  geom_point(show.legend = FALSE, size = 6, color = "black") +
  geom_errorbar(show.legend = FALSE, ymin = Mean - FLSD, ymax = Mean + FLSD, width =   6, size = 2.1, color = "black") +
  scale_color_manual(values = c("WxRED" = "firebrick1", "WxGREEN" = "green3",          "WxYELLOW" = "gold")) +
  scale_x_continuous(breaks = seq(450, 750, 50)) +
  scale_y_continuous(breaks = seq(20, 120, 20)) +
  xlab("Backlight (cd/m2)") +
  ylab("Score")

Same thing, you're calling ymin = Mean - FLSD outside an aes(), so Mean and FLSD are expected to be variable names, not column names.

1 Like

This is interesting. I've been thinking of variable and column names as equivalents (although there will be variables that aren't column names). I tried this:

ggplot(BxTC, aes(x = Backlight, y = Mean, fill = TargetColor)) +
  geom_line(show.legend = FALSE, size = 2.4, color = "black") +
  geom_point(show.legend = FALSE, size = 6, color = "black") +
  geom_errorbar(show.legend = FALSE, ymin = BxTC$Mean - BxTC$FLSD, ymax = BxTC$Mean +   BxTC$FLSD, width = 6, size = 2.1, color = "black") +
  scale_color_manual(values = c("WxRED" = "firebrick1", "WxGREEN" = "green3",          "WxYELLOW" = "gold")) +
  scale_x_continuous(breaks = seq(450, 750, 50)) +
  scale_y_continuous(breaks = seq(0, 120, 20)) +
  xlab("Backlight (cd/m2)") +
  ylab("Score")

It produced:

which is a huge improvement, but there's obviously still something wrong with my color specifications.

Lines and points have a color and not a fill. Try

ggplot(BxTC, aes(x = Backlight, y = Mean, color = TargetColor)) +
  geom_line(show.legend = FALSE, size = 2.4) +
  geom_point(show.legend = FALSE, size = 6) +
  geom_errorbar(show.legend = FALSE, ymin = BxTC$Mean - BxTC$FLSD, ymax = BxTC$Mean +   BxTC$FLSD, width = 6, size = 2.1, color = "black") +
  scale_color_manual(values = c("WxRED" = "firebrick1", "WxGREEN" = "green3",          "WxYELLOW" = "gold")) +
  scale_x_continuous(breaks = seq(450, 750, 50)) +
  scale_y_continuous(breaks = seq(0, 120, 20)) +
  xlab("Backlight (cd/m2)") +
  ylab("Score")
1 Like

That works but omits the black outlining. I expect you knew that.

I notice my y-axis scaling is sufficient only to display the means. The error bars are cut off (unlike my original figure).

I tried :

ggplot(BxTC, aes(x = Backlight, y = Mean, color = TargetColor), group = factor(TargetColor)) +
  geom_line(show.legend = FALSE, size = 2.4, color = "black") +
  geom_point(show.legend = FALSE, size = 6, color = "black") +
  geom_errorbar(show.legend = FALSE, ymin = BxTC$Mean - BxTC$FLSD, ymax = BxTC$Mean +   BxTC$FLSD, width = 6, size = 2.1, color = "black") +
  geom_line(show.legend = FALSE, size = 2.1) +
  geom_point(show.legend = FALSE, size = 4) +
  geom_errorbar(show.legend = FALSE, ymin = BxTC$Mean - BxTC$FLSD, ymax = BxTC$Mean +   BxTC$FLSD, width = 6, size = 2.1) +
  scale_color_manual(values = c("WxRED" = "firebrick1", "WxGREEN" = "green3",          "WxYELLOW" = "gold")) +
  scale_x_continuous(breaks = seq(450, 700, 50)) +
  scale_y_continuous(breaks = seq(0, 120, 20)) +
  xlab("Backlight (cd/m2)") +
  ylab("Score")

This overlapping approach seems to work for the points and lines (although the black lines don't respect the group statement). Don't know why the black error bars don't appear.

Please post the output of

dput(BxTC)
1 Like

Not sure that's the problem (as FJCC mentioned, it'll be easier to answer with actual data to look at), but I would strongly recommend putting any variable aesthetics inside an aes() call:

geom_errorbar(aes(ymin = Mean - FLSD, ymax = Mean + FLSD),
              show.legend = FALSE, width = 6, size = 2.1, color = "black") +
1 Like

Try moving group = ... inside the aes().

1 Like

Those last 2 corrections did the trick! New version:

ggplot(BxTC, aes(x = Backlight, y = Mean, color = TargetColor, group = factor(TargetColor))) +
  geom_line(show.legend = FALSE, size = 2, color = "black") +
  geom_point(show.legend = FALSE, size = 6, color = "black") +
  geom_errorbar(show.legend = FALSE, ymin = BxTC$Mean - BxTC$FLSD, ymax = BxTC$Mean +   BxTC$FLSD, width = 6, size = 2, color = "black") +
  geom_line(show.legend = FALSE, size = 1) +
  geom_point(show.legend = FALSE, size = 4) +
  geom_errorbar(show.legend = FALSE, ymin = BxTC$Mean - BxTC$FLSD, ymax = BxTC$Mean +   BxTC$FLSD, width = 6, size = 1) +
  scale_color_manual(values = c("WxRED" = "firebrick1", "WxGREEN" = "green3",          "WxYELLOW" = "gold")) +
  scale_x_continuous(breaks = seq(450, 700, 50)) +
  scale_y_continuous(breaks = seq(0, 120, 20)) +
  xlab("Backlight (cd/m2)") +
  ylab("Score")

Is there a remaining syntax error that's preventing the y-axis from scaling itself properly?

I fixed my remaining problem by adding a coord_cartesian statement. Don't know why it's needed, but it works:

ggplot(BxTC, aes(x = Backlight, y = Mean, color = TargetColor, group =                 factor(TargetColor))) +
  geom_line(show.legend = FALSE, size = 2, color = "black") +
  geom_point(show.legend = FALSE, size = 6, color = "black") +
  geom_errorbar(show.legend = FALSE, ymin = BxTC$Mean - BxTC$FLSD, ymax = BxTC$Mean +     BxTC$FLSD, width = 6, size = 2, color = "black") +
  geom_line(show.legend = FALSE, size = 1) +
  geom_point(show.legend = FALSE, size = 5) +
  geom_errorbar(show.legend = FALSE, ymin = BxTC$Mean - BxTC$FLSD, ymax = BxTC$Mean +   BxTC$FLSD, width = 6, size = 1) +
  scale_color_manual(values = c("WxRED" = "firebrick1", "WxGREEN" = "green3",            "WxYELLOW" = "gold")) +
  scale_x_continuous(breaks = seq(450, 700, 50)) +
  scale_y_continuous(breaks = seq(0, 120, 20)) +
  coord_cartesian(ylim = c(0, 120)) +
  xlab("Backlight (cd/m2)") +
  ylab("Score")

Thanks to both of you for this tutorial. You've improved my understanding of how aes statements work, which is more than I asked about initially. I flipped a coin to choose the Solution because you both contributed equally.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.