Skip to content

Instantly share code, notes, and snippets.

@wch
Created August 3, 2012 19:06
Show Gist options
  • Select an option

  • Save wch/3250485 to your computer and use it in GitHub Desktop.

Select an option

Save wch/3250485 to your computer and use it in GitHub Desktop.
Creating a new scale for ggplot2
# 1. functions for yearmon transformer ================
# Convert from numeric to yearmon
to_yearmon <- function(x) as.yearmon(x)
# Inverse: convert from yearmon to numeric
from_yearmon <- function(x) {
if (!inherits(x, "yearmon")) {
stop("Invalid input: date_yearmon works with objects of class yearmon only",
call. = FALSE)
}
as.numeric(x)
}
# Returns a _function_ that takes a yearmon object as input and returns a
# yearmon object as output, with approximately n breaks, using pretty_breaks().
# Can't just use pretty_breaks() directly, since it changes yearmon objects
# to numeric.
# n is number of breaks
# (Does this really need to be a function returning a function?)
yearmon_breaks <- function(n = 5) {
function(x) as.yearmon(pretty_breaks(n)(x))
}
# Takes a yearmon as input and returns a string representation of it
yearmon_format <- function(x) {
paste("foo", as.numeric(x))
}
# 2. yearmon transformation object ================
# Returns a function that creates a transformer
# (Does this really need to be a function returning a function?)
yearmon_trans <- function() {
require(scales)
trans_new("yearmon", transform = from_yearmon, inverse = to_yearmon,
breaks = yearmon_breaks(), format = yearmon_format)
}
# 3. Create the x and y scales for yearmon ================
# This tells ggplot2 what scale to look for, for yearmon
scale_type.yearmon <- function(x) "yearmon"
scale_yearmon <- function(aesthetics, ...) {
continuous_scale(aesthetics, "yearmon", identity,
guide = "none", trans = yearmon_trans(), ...)
}
scale_x_yearmon <- function(...) {
scale_yearmon(aesthetics = c("x", "xmin", "xmax", "xend"), ...)
}
scale_y_yearmon <- function(...) {
scale_yearmon(aesthetics = c("y", "ymin", "ymax", "yend"), ...)
}
# =====================================================================
# Usage example
# =====================================================================
library(zoo)
dates <- as.yearmon(seq(as.Date('2008-12-01'), by='month', to=as.Date('2012-06-01')))
data <- data.frame(Date=dates, value=rnorm(length(dates)))
# If you use scale_x_continuous and specify the transformer, you only need
# sections 1 and 2 from above.
ggplot(data, aes(x=Date, y=value)) + geom_line() +
scale_x_continuous(trans = yearmon_trans())
# To have ggplot automatically figuure out the scale, you also need section 3
ggplot(data, aes(x=Date, y=value)) + geom_line()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment