It's hard to tell without the data, but I think the p you're plotting might be outside of your data frame.
Could you please turn this into a self-contained reprex (short for reproducible example)? You're almost there, it's just that since no one else has your test2.csv file, we can't re-create it. It will help us help you if we can be sure we're all working with/looking at the same stuff.
You can probably just include the tidied dataframe, since the focus of your problem is on ggplot.
Personally I would create a new variable in the table (a fill_col column) with value according to your filter. Then you can use this variable on the fill aesthetic.
It is a wild guess as we need a reprex to be on the same page (follow @mara advice, but i would modify you code like this
perf.project <- read.csv2("test2.csv",header=TRUE,sep=";",stringsAsFactors=FALSE,encoding="UTF-8",dec=".",check.names=FALSE)
perf.project.tdy <- perf.project %>%
gather("types", "perf", 6:6) %>%
# Create the variable you need for the plot
mutate(pas = factor(pas, levels = unique(pas), ordered=TRUE),
fill_col = case_when(
perf > 0 ~ "green",
perf <= -4 ~ "red",
TRUE ~ "orange"
barwidth <- 0.95
# ggplot work on a data.frame and you need to provide variables (columns) of that DF (without any $)
ggplot(perf.project.tdy, aes(x = pas , y = perf)) + # you provide fill after
geom_col(fill = fill_col,
width = barwidth) +
# aes x and y are already provided
geom_text(aes(label=paste(perf, "%")), vjust=1.6, color="black", size=3.5)
It may not work as I don't have your data to test. Basically, what I wanted to show:
tidyverse has tools like dplyr to efficiently work with data. (like case_when for recoding more than 2 level and mutate to modify variables. )
ggplot2 works a data.frame (provide in data argument), then you map variables (columns) to aesthetics and scales. You don't need to provide vector value with $. Just the column name.
Knowing that, put everythink in your data. You can add a column with value corresponding to color for fill aesthetics.
You need to put the data in ggplot call and stop using $ - just use the column name to map variable from data to layers in ggplot. Put in ggplot call the common layer too. the geom and their specific layer. They could also go into the first ggplot call too.
You need also to map fill_col variable to fill aesthetic, so in a aes() call. if not it won't map the variable but only use the value. Your issue may come from here.
You need to follow my example and try to understand it.
Hello, thanks to your help.
So, you will find hereafter the ggplot function and the graph.
Anyway, there is now a problem : the text of the legend don't match with the color.
The color is defined with the value of the variable fill_col (it's seem correct)
Oh yes, I forgot about that! Thanks also @mara for the reminder.
There a function inside ggplot2 for this kind of task where the variable contains aesthetic values. In your example, this is the case as you have the color vlaue in the fill_col variable, as I adviced. I was just missing a piece: add scale_fill_identify() to your ggplot. see the documentation for detail, for example, you need to add guide="legend" if you want to keep the legend.