traggatmot
traggatmot

Reputation: 1463

Label ggplot Geom_Bar with total categorical value

With This CSV:

Year,Permanent Wetland Loss,Permit Wetlands CRE,Permit Conservation,ARM Conservation,ARM Restoration,ARM Enhancement,Conservation_Total,EnRes_Total
2008,61,4,1271,,,,1271,4
2009,73,4,2707,1403,,,4110,4
2010,70,26,1440,1030,,,2470,26
2011,52,32,781,2537,,,3318,32
2012,41,8,211,2675,,,2886,8
2013,68,21,265,2191,6.6,80,2456,107.6
2014,48,1,114,1165,,,1279,1
2015,73,0,947,2381,11,,3328,11
2016,33,18,116,3751,,,3867,18
2017,59,15,136,,,,136,15
2018,77,1,89,8177,,,8266,1

I am executing this code:

library(reshape2) # for melt
input_df <- read.csv("ARM_PERMIT_COMB.csv", header=TRUE)
names(input_df) <- c('Year', 'Wetland Loss','Restoration/Enhancement - Permit','Conservation - Permit',
                   'Conservation - ARM', 'Restoration - ARM', 'Enhancement - ARM', 'Con - Total', 'EnRes - Total') 

input_df <- input_df[,c(1,5,4,3,6,7,2)]
melted <- melt(input_df, "Year")

melted$cat <- ''
melted[melted$variable == 'Wetland Loss',]$cat <- "Loss"
melted[melted$variable == 'Restoration/Enhancement - Permit',]$cat <- "Enhancement / Restoration"
melted[melted$variable == 'Restoration - ARM',]$cat <- "Enhancement / Restoration"
melted[melted$variable == 'Enhancement - ARM',]$cat <- "Enhancement / Restoration"
melted[melted$variable == 'Conservation - ARM',]$cat <- "Conservation"
melted[melted$variable == 'Conservation - Permit',]$cat <- "Conservation"


ggplot(melted, aes(x = cat, y = value, fill = variable)) + 
  geom_bar(stat = 'identity', position = 'stack') + facet_grid(~ Year) + 
  labs(title = 'Wetlands Loss, Conservation, Enhancement, Restoration, ', y='Acres', x='', subtitle = 'Years 2008 - 2018') +
  theme(plot.title = element_text(hjust = 0.5), plot.subtitle = element_text(hjust = 0.5)) + 
  theme(axis.text.x = element_text(angle = 90, vjust = 0.3, hjust=1)) +
  scale_fill_manual(values=c("chartreuse2","green4", "steelblue3", "yellow3","orangered2", "grey33","white","white"), 
                    name="Impacts and\nMitigation") + 
  geom_text(aes(label=value), vjust = -3)

To generate this graph:

enter image description here

Which is perfect in every way except for the fact that I want the labels to reflect the sums of the entire stacked bar and not all the individual parts that make up the stacked bar.

Zoom in:

enter image description here

Things I have tried: - plotting a chart behind this one with white bars that this plots over - wasn't able to figure that out. - trying to get the geom_text to reference a different dataframe taht represented the totals (geom_text(aes(label=melted_total$value), vjust = -3)) which didn't work.

EDIT:

This code gets me very very close to what I want, just have to figure out how to hide the two 'Totals' in the legend:

library(reshape2) # for melt
input_df <- read.csv("ARM_PERMIT_COMB.csv", header=TRUE)
input_total_df <- input_df[,c(1,2,8,9)]

names(input_df) <- c('Year', 'Wetland Loss','Restoration/Enhancement - Permit','Conservation - Permit',
                   'Conservation - ARM', 'Restoration - ARM', 'Enhancement - ARM', 'Con - Total', 'EnRes - Total')   
names(input_total_df) <- c('Year', 'Wetland Loss','Con - Total', 'EnRes - Total')   


input_df <- input_df[,c(1,5,4,3,6,7,2)]
melted <- melt(input_df, "Year")
melted_total <- melt(input_total_df, "Year")


melted$cat <- ''
melted[melted$variable == 'Wetland Loss',]$cat <- "Loss"
melted[melted$variable == 'Restoration/Enhancement - Permit',]$cat <- "Enhancement / Restoration"
melted[melted$variable == 'Restoration - ARM',]$cat <- "Enhancement / Restoration"
melted[melted$variable == 'Enhancement - ARM',]$cat <- "Enhancement / Restoration"
melted[melted$variable == 'Conservation - ARM',]$cat <- "Conservation"
melted[melted$variable == 'Conservation - Permit',]$cat <- "Conservation"

melted_total$cat <- ''
melted_total[melted_total$variable == 'Wetland Loss',]$cat <- "Loss"
melted_total[melted_total$variable == 'Con - Total',]$cat <- "Conservation"
melted_total[melted_total$variable == 'EnRes - Total',]$cat <- "Enhancement / Restoration"


ggplot(melted, aes(x = cat, y = value, fill = variable)) + 
  geom_bar(stat = 'identity', position = 'stack') + facet_grid(~ Year) + 
  labs(title = 'Wetlands Loss, Conservation, Enhancement, Restoration, ', y='Acres', x='', subtitle = 'Years 2008 - 2018') +
  theme(plot.title = element_text(hjust = 0.5), plot.subtitle = element_text(hjust = 0.5)) + 
  theme(axis.text.x = element_text(angle = 90, vjust = 0.3, hjust=1)) +
  scale_fill_manual(values=c("white","chartreuse2","green4", "steelblue3", "white", "yellow3","orangered2", "grey33", "white"), 
                    name="Impacts and\nMitigation") + 
  geom_text(data=melted_total, aes(label=value), vjust = -1, size=2)

Output:

enter image description here

Upvotes: 2

Views: 1554

Answers (2)

erocoar
erocoar

Reputation: 5893

reshape2 has been replaced by tidyr's spread() and gather() operations. You can greatly simplify your code by using the tidyverse. Also, it is probably bad practice to fill your factors to make them invisible. It is easier to set inherit.aes = FALSE and set new aes() parameters.

Consider this code:

library(tidyverse)

input_df <- read_csv("ARM_PERMIT_COMB.csv") %>%
  magrittr::set_colnames(
    c('Year', 'Wetland Loss','Restoration/Enhancement - Permit',
      'Conservation - Permit', 'Conservation - ARM', 'Restoration - ARM',
      'Enhancement - ARM', 'Con - Total', 'EnRes - Total')
    ) %>% 
  select(-contains("Total")) %>%
  gather(Variable, Value, -Year) %>%
  mutate(Category = case_when(
    Variable == "Wetland Loss" ~ "Loss",
    str_detect(Variable, "Restoration|Enhancement") ~ "Enhancement / Restoration",
    str_detect(Variable, "Con") ~ "Conservation",
    TRUE ~ "Enhancement / Restoration"
  ))

ggplot(input_df, aes(x = Category, y = Value, fill = Variable)) +
  geom_bar(stat = "identity", position = "stack") + 
  facet_grid(~Year) +
  labs(title = 'Wetlands Loss, Conservation, Enhancement, Restoration, ', 
       y = 'Acres', x = '', subtitle = 'Years 2008 - 2018') +
  theme(plot.title = element_text(hjust = 0.5), 
        plot.subtitle = element_text(hjust = 0.5),
        axis.text.x = element_text(angle = 90, vjust = 0.3, hjust = 1)) +
  scale_fill_manual(values = c("chartreuse2","green4", "steelblue3", 
                               "yellow3","orangered2", "grey33"), 
                    name = "Impacts and\nMitigation") + 
  geom_text(data = input_df %>% 
              group_by(Year, Category) %>% 
              summarise(Value = sum(Value, na.rm = TRUE)),
            aes(label = Value, x = Category, y = Value), inherit.aes = FALSE,
            vjust = -1, size = 2)

Upvotes: 2

traggatmot
traggatmot

Reputation: 1463

Got it - Had to adjust the breaks in the scale_fill_manual:

 scale_fill_manual(breaks=c('Year', 'Wetland Loss','Restoration/Enhancement - Permit','Conservation - Permit',
                             'Conservation - ARM', 'Restoration - ARM', 'Enhancement - ARM'),
                    values=c("white","chartreuse2","green4", "steelblue3", "white", "yellow3","orangered2", "grey33", "white"), 
                    name="Impacts and\nMitigation") +

And that cut out the white legend entries.

Upvotes: 0

Related Questions