Reputation: 820
I would like my bars to be red when the value is below zero. This is not the actual data I am working with but I hope this will create a reproduce-able example:
library(ggplot2)
library(car)
mtcars$carnames <- rownames(mtcars)
rownames(mtcars) <- 1:nrow(mtcars)
subsetCars <- as.data.frame(head(mtcars, n = 20))
subsetCars[1,4] <- -50
myplot.p <- ggplot(subsetCars, aes(x = subsetCars$carnames, y = subsetCars$hp))
myplot.p + geom_bar(stat = 'identity',
fill = ifelse(subsetCars$hp > 0, "lightblue", "firebrick")) +
coord_flip()
One bar is colored red, but not the one with the negative value. I have a similar problem with the current viz I am working on as well. Advice?
Upvotes: 0
Views: 3762
Reputation: 36
The problem you are having is that when you are specifying the fill, ggplot is not assigning that aesthetic in the same order that it is for the names. So to make sure the order is preserved, you need to put the greater than zero variable with the other aesthetics.
The unfortunate side effect of this is you need to manually set the colors and remove the fill scale legend.
ggplot(subsetCars, aes(x = subsetCars$carnames, y = subsetCars$hp,
fill = hp > 0)) +
geom_bar(stat = 'identity') +
coord_flip() +
scale_fill_manual(values = c("TRUE" = "lightblue",
"FALSE" = "firebrick")) +
theme(legend.position = "none")
I hope that helps!
Upvotes: 1
Reputation: 13118
Note that your fill
argument in geom_bar
takes a vector created by ifelse
, of which the first element is "firebrick" and all other elements are "lightblue". So the first (bottom-most) bar will be filled with red. However, the first bar does not correspond to the row with the negative value, since the observations have been re-ordered by carnames
in alphabetical order.
A more idiomatic way of plotting your desired chart is
myplot.p <- ggplot(subsetCars, aes(x = carnames, y = hp, fill = hp < 0))
myplot.p + geom_bar(stat = 'identity') +
scale_fill_manual("Negative hp", values = c("lightblue", "firebrick")) +
coord_flip()
where the $
subsetting is unnecessary, as @alistaire pointed out, and the fill
aesthetic can be stated in ggplot()
.
Upvotes: 2