I have a data set that documents the energy use of three buildings. I have a melted data frame that can be mimicked from the diamonds set:
data <- melt(diamonds[,c('depth','table','cut','color')],id=c('cut','color'))
Essentially, I have heating ('depth') and cooling ('table') data for each month('cut') from three different buildings (7 'color' factors). I would like to plot the three buildings (7 'color' factors) side by side in a bar plot for each month ('cut').
I want the bars representing either cooling ('table') or heating ('depth') to vary their shade based on the building ('color' factor) while remaining grouped by month ('cut'). This is a bad way to visualize the diamonds data, but should work well for buildings as their heating and cooling months typically don't overlap. So far I have:
p <- ggplot(data,
aes(color,value,group=cut))
p <- p + geom_bar(stat = 'identity',
position = 'dodge',
aes(fill = variable))
print(p)
I tried playing with scale_fill_manual, but couldn't think of a strategy that works:
colours <- c('#0000FF', '#0033FF', '#0066FF', '#FF0000', '#FF3300', '#FF6600')
p <- p + scale_fill_manual(values = colours,
group = data$variable)
With some trickery, it is possible. Deriving a data set based on diamonds was very good, but I want to work with a smaller data set
set.seed(1234)
data <-
expand.grid(month = month.abb,
building = c("Building A", "Building B", "Building C"),
hc = c("Heating", "Cooling"))
data$value <- rnorm(nrow(data), 60, 10)
You want your fill colour to be based both on the variable (hc
) and the building (building
), so set it to that interaction.
ggplot(data, aes(building,value,group=month)) +
geom_bar(stat = 'identity',
position = 'dodge',
aes(fill = interaction(building, hc)))
We can pick colors that represent different near shades to make these more like what you want. I used the middle of the "Blues" and "Reds" of the RColorBrewer
palettes.
colours <- c("#FC9272", "#FB6A4A", "#EF3B2C", "#9ECAE1", "#6BAED6", "#4292C6")
# library("RColorBrewer")
# colours <- c(brewer.pal(9,"Reds")[4:6], brewer.pal(9,"Blues")[4:6])
and used scale_fill_manual
to assign these colours.
ggplot(data, aes(building,value,group=month)) +
geom_bar(stat = 'identity',
position = 'dodge',
aes(fill = interaction(building, hc))) +
scale_fill_manual(values=colours)
The real trickery is in making the legend less convoluted. I just list 2 of the levels (the middle building in terms of color) and give them different names (and a different title for the legend).
ggplot(data, aes(building,value,group=month)) +
geom_bar(stat = 'identity',
position = 'dodge',
aes(fill = interaction(building, hc))) +
scale_fill_manual("Heating/cooling",
values=colours,
breaks=c("Building B.Heating", "Building B.Cooling"),
labels=c("Heating", "Cooling"))