Skip to content

Commit

Permalink
Improve interaction of geom_vline/geom_hline with coord_flip by imple…
Browse files Browse the repository at this point in the history
…menting non-finite positions
  • Loading branch information
hadley committed Dec 10, 2009
1 parent c4a3981 commit 1f37b8d
Show file tree
Hide file tree
Showing 12 changed files with 43 additions and 13 deletions.
5 changes: 4 additions & 1 deletion NEWS
Expand Up @@ -45,4 +45,7 @@ ggplot2 0.8.5 (2009-XX-XX) ----------------------------------------
* coord_trans now respects scale expand parameter (expansion occurs after
tranformation) (Fixes #14)
* coord_cartesian now correctly sets limits when one or both of the position
scales are non-linear. (Fixes #17)
scales are non-linear. (Fixes #17)
* x and y position can be set to Inf or -Inf to refer to the top/right and
bottom/left extents of the panel (implements #18)
* geom_hline and geom_vline now work with coord_flip (fixes #30)
2 changes: 1 addition & 1 deletion R/coord-.r
Expand Up @@ -7,7 +7,7 @@ Coord <- proto(TopLevel, expr={
# Rescaling at coord level should not be clipped: this is what
# makes zooming work
rescale_var <- function(., data, range, clip = FALSE) {
rescale(data, 0:1, range, clip = clip)
rescale(data, 0:1, range, clip = clip)
}

munch <- function(., data, details, npieces=50) {
Expand Down
3 changes: 2 additions & 1 deletion R/coord-cartesian-.r
Expand Up @@ -7,7 +7,8 @@ CoordCartesian <- proto(Coord, expr={
rescale_x <- function(data) .$rescale_var(data, details$x.range)
rescale_y <- function(data) .$rescale_var(data, details$y.range)

transform_position(data, rescale_x, rescale_y)
data <- transform_position(data, rescale_x, rescale_y)
transform_position(data, trim_infinite_01, trim_infinite_01)
}

compute_ranges <- function(., scales) {
Expand Down
2 changes: 2 additions & 0 deletions R/coord-cartesian-flipped.r
Expand Up @@ -5,6 +5,8 @@ CoordFlip <- proto(CoordCartesian, expr={
rescale_y <- function(data) .$rescale_var(data, details$y.range)

data <- transform_position(data, rescale_y, rescale_x)
data <- transform_position(data, trim_infinite_01, trim_infinite_01)

rename(data, c(
x = "y", y = "x",
xend = "yend", yend = "xend",
Expand Down
2 changes: 1 addition & 1 deletion R/coord-polar.r
Expand Up @@ -69,7 +69,7 @@ CoordPolar <- proto(Coord, {
transform <- function(., data, details) {
data <- .$rename_data(data)

within(data, {
data <- within(data, {
r <- .$r_rescale(r, details)
theta <- .$theta_rescale(theta, details)

Expand Down
3 changes: 2 additions & 1 deletion R/coord-transform.r
Expand Up @@ -12,7 +12,8 @@ CoordTrans <- proto(CoordCartesian, expr={
trans_x <- function(data) .$transform_x(data, details$x.range)
trans_y <- function(data) .$transform_y(data, details$y.range)

transform_position(data, trans_x, trans_y)
data <- transform_position(data, trans_x, trans_y)
transform_position(data, trim_infinite_01, trim_infinite_01)
}
transform_x <- function(., data, range) {
rescale(.$xtr$transform(data), 0:1, range, clip = FALSE)
Expand Down
4 changes: 2 additions & 2 deletions R/geom-hline.r
Expand Up @@ -9,8 +9,8 @@ GeomHline <- proto(Geom, {
}

draw <- function(., data, scales, coordinates, ...) {
data$x <- scales$x.range[1]
data$xend <- scales$x.range[2]
data$x <- -Inf
data$xend <- Inf

GeomSegment$draw(unique(data), scales, coordinates)
}
Expand Down
1 change: 1 addition & 0 deletions R/geom-segment.r
@@ -1,6 +1,7 @@
GeomSegment <- proto(Geom, {
draw <- function(., data, scales, coordinates, arrow=NULL, ...) {
if (!coordinates$muncher()) {
browser()
return(with(coordinates$transform(data, scales),
segmentsGrob(x, y, xend, yend, default.units="native",
gp = gpar(col=alpha(colour, alpha), lwd=size * .pt,
Expand Down
4 changes: 2 additions & 2 deletions R/geom-vline.r
Expand Up @@ -9,8 +9,8 @@ GeomVline <- proto(Geom, {
}

draw <- function(., data, scales, coordinates, ...) {
data$y <- scales$y.range[1]
data$yend <- scales$y.range[2]
data$y <- -Inf
data$yend <- Inf

GeomSegment$draw(unique(data), scales, coordinates)
}
Expand Down
3 changes: 2 additions & 1 deletion R/scale-continuous-.r
Expand Up @@ -61,7 +61,8 @@ ScaleContinuous <- proto(Scale, funEnvir = globalenv(), {
# By default, a continuous scale does no transformation in the mapping stage
# See scale_size for an exception
map <- function(., values) {
as.numeric(ifelse(values %inside% .$output_set(), values, NA))
trunc <- !is.finite(values) | values %inside% .$output_set()
as.numeric(ifelse(trunc, values, NA))
}

# By default, the range of a continuous scale is the same as its
Expand Down
18 changes: 17 additions & 1 deletion R/utilities-position.r
Expand Up @@ -11,4 +11,20 @@ expand_range <- function(range, mul = 0, add = 0, zero = 0.5) {
} else {
range + c(-1, 1) * (diff(range) * mul + add)
}
}
}

# Trim non-finite numbers to specified range
#
# @keywords internal
# @alias trim_infinite_01
trim_infinite <- function(x, range) {
x[x == -Inf] <- range[1]
x[x == Inf] <- range[2]
x
}

trim_infinite_01 <- function(x) {
trim_infinite(x, c(0, 1))
}


9 changes: 7 additions & 2 deletions R/utilities.r
Expand Up @@ -136,8 +136,13 @@ rescale <- function(x, to=c(0,1), from=range(x, na.rm=TRUE), clip = TRUE) {
warning("Categorical variable automatically converted to continuous", call.=FALSE)
x <- as.numeric(x)
}
scaled <- (x-from[1])/diff(from)*diff(to) + to[1]
if (clip) ifelse(scaled %inside% to, scaled, NA) else scaled
scaled <- (x - from[1]) / diff(from) * diff(to) + to[1]

if (clip) {
ifelse(!is.finite(scaled) | scaled %inside% to, scaled, NA)
} else {
scaled
}
}


Expand Down

0 comments on commit 1f37b8d

Please sign in to comment.