Search code examples
rggplot2geom-barnegative-numberyaxis

How to make upright bars using geom_bar with negative y values?


I am trying to make the following bar plot using ggplot (if base r is simpler that is okay, I am just more familiar with ggplot): GoalPlot

This seems simple to me but for some reason, no matter what I try it is not working.

My df:

structure(list(Target_depth_mean1 = c(3, 4, 5, 6, 7, 8, 9, 10, 
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22), TS_mean1 = c(-47, 
-45, -40, -43, -40, -39, -42, -42, -37, -41, -41, -38, -40, -41, 
-41, -40, -42, -42, -41, -38)), row.names = c(NA, -20L), class = c("tbl_df", 
"tbl", "data.frame"))

I have tried the following:

ggplot(STmean, aes(x=Target_depth_mean1, y=TS_mean1)) +
  geom_bar(stat="identity", position = "dodge") #almost what I want but I don't want the bars upside down, also tried geom_col instead but still upside down bars

and...

ggplot(STmean, aes(x=Target_depth_mean1, y=TS_mean1)) +
  geom_bar(stat="identity", position = "dodge") +
  ylim(-48,-36) #doesn't plot anything

and...

ggplot(STmean, aes(x=Target_depth_mean1, y=TS_mean1)) +
  geom_bar(stat="identity") +
  coord_cartesian(ylim = c(-50,-30)) #still upside down bars

and...

ggplot(STmean, aes(x=Target_depth_mean1, y=TS_mean1)) +
  geom_bar(stat="identity", position = "dodge") +
  scale_y_reverse() #plots upright but I need the values reversed too (smaller on bottom)

and...

ggplot(STmean, aes(x=Target_depth_mean1, y=TS_mean1)) +
  geom_bar(stat="identity", position = "dodge") +
  scale_y_reverse(limits=c(-50,-30)) #doesn't plot anything

and... library(scales)

ggplot(STmean, aes(x=Target_depth_mean1, y=TS_mean1)) +
  geom_bar(stat="identity") +
  scale_y_continuous(limits = c(-50, -30), oob= rescale_none) #still upside down, and if I switch to limits = c(-30,-50) plots upright but again need smaller values (-50) on bottom of y axis...

and...

ggplot(STmean, aes(x=Target_depth_mean1, y=TS_mean1)) +
  geom_bar(stat="identity") +
  coord_cartesian(ylim = range(STmean$TS_mean1)) #upside down!

I also tried making TS values positive and adding the negative symbol after...

STmean1 <- STmean %>%
  mutate(across(c("TS_mean1"), abs))

trying to plot this...

ggplot(STmean1, aes(x=Target_depth_mean1, y=TS_mean1)) +
  geom_bar(stat="identity") +
  scale_y_continuous(
    limits = c(50, 30), 
                     oob= rescale_none,
                     labels=function(x) paste0("-",x)) #upside down

What am I doing wrong? I feel like I am so close but can't get it to work. I've been trying for hours and looked at other SO questions, but no luck... Tried the answer in this question, but didn't work.


Solution

  • Based on this answer, you can do the following:

    ggplot(STmean, aes(x=Target_depth_mean1, y=TS_mean1 - min(TS_mean1))) +
      geom_bar(stat="identity", position = "dodge") +
      scale_y_continuous(breaks = seq(from = min(STmean$TS_mean1),
                                      to = max(STmean$TS_mean1), by = 1) - min(STmean$TS_mean1),
                         labels = seq(from = min(STmean$TS_mean1),
                                      to = max(STmean$TS_mean1), by = 1)) + 
      ylab("TS_mean1")