GregRousell
GregRousell

Reputation: 1077

How do I create bar charts in R where the starting point of the bar is greater than zero?

I'm trying to create a series of bar charts (to be replicated for multiple sites) that highlight the difference between the main site and the satellite locations. I can come somewhat close using geom_point, but I'd like to have them represented as bar charts, where the bar starts at the lowest point, there are labels for the main site and satellite locations, as well as the difference between them. Here is some sample code and screenshots of what I have, and an idea of what I'd like it to look like.

library(ggplot2)
library(dplyr)

site <- c("Site A", "Main Site", "Site A", "Main Site", "Site A", "Main Site")
year <- c("2013", "2013", "2014", "2014","2015", "2015" )
value <- c(57, 74, 60, 50, 60, 68)

df <- data.frame (site, year, value)

df %>%
  mutate (label = paste0(site, " (", value, ")")) %>%
  ggplot (aes (x = year, y = value, group = site, colour = site)) +
  geom_point (size = 0.5) +
  scale_y_continuous(limits = c (0,100)) +
  geom_text (aes(label = label))

enter image description here

enter image description here

Upvotes: 1

Views: 474

Answers (2)

Mark Peterson
Mark Peterson

Reputation: 9560

Following up on the comment from @gregor, you can try the below (note dcast is from reshape2 and the heavy use of dplyr

df %>%
  dcast(year~site) %>%
  mutate(midpt = (`Main Site` + `Site A`)/2
         , dir = factor( (`Main Site` - `Site A`) > 0
                         , levels = c(FALSE,TRUE)
                         , labels = c("Negative", "Positive"))
         , diff = abs(`Main Site` - `Site A`)) %>%
  ggplot(aes(x = year
             , y = midpt
             , fill = dir
             , height = diff)) +
  geom_tile() +
  scale_fill_manual(values = c("Positive" = "darkgreen"
                               , "Negative" = "red3"))

enter image description here

If you have more than 2 sites, you would likely want a more flexible solution, probably using dplyr directly.

Upvotes: 1

GregRousell
GregRousell

Reputation: 1077

Using the comment from @Gregor I managed to come up with something that will work. Probably isn't the most elegant solution but will work for now.

df %>%
  spread(site, value) %>%
  mutate (diff = SiteA - MainSite) %>% 
  mutate (AboveBelow = recode (diff," -100:-1 = 'Below';
                               0 = 'No Difference';
                               1:100 = 'Above'")) %>%
  ggplot() +
  scale_x_continuous(name = "Year", breaks = c (2013, 2014, 2015)) + 
  scale_y_continuous(name = "Percentage", limits = c(0,100)) + 
  geom_rect (aes (xmin = year - 0.33, xmax = year + 0.33, ymin = SiteA, ymax = MainSite, fill = AboveBelow)) +
  geom_text (aes (x = year, y = ifelse (diff < 0, MainSite + 5, MainSite - 3), label = paste0("MainSite - ", MainSite))) +
  geom_text (aes (x = year, y = ifelse (diff < 0, SiteA - 3, SiteA +5), label = paste0("SiteA - ", SiteA))) +
  geom_text (aes (x = year, y = MainSite + (diff/2), label = diff)) + 
  scale_fill_manual(values = c("green", "red", "white" ))

Gives me this:

enter image description here

Upvotes: 1

Related Questions