Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quick approximation for map projections #922

Merged
merged 4 commits into from
Mar 25, 2014
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Quick approximation for map projections
Instead of reprojecting everything, we just set the aspect ratio
of the plot to the ratio between the length of one degree of lat
over one degree of lon.
  • Loading branch information
jiho committed Feb 27, 2014
commit 7637548616f7fdf1a20a8239c9b0b91e5458595d
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Collate:
'coord-map.r'
'coord-munch.r'
'coord-polar.r'
'coord-quickmap.R'
'coord-transform.r'
'facet-.r'
'facet-grid-.r'
Expand Down
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,14 @@ export(borders)
export(calc_element)
export(continuous_scale)
export(coord)
export(coord_aspect)
export(coord_cartesian)
export(coord_equal)
export(coord_fixed)
export(coord_flip)
export(coord_map)
export(coord_polar)
export(coord_quickmap)
export(coord_trans)
export(cut_interval)
export(cut_number)
Expand Down Expand Up @@ -289,6 +291,7 @@ export(position_identity)
export(position_jitter)
export(position_stack)
export(qplot)
export(quickmap)
export(quickplot)
export(rel)
export(resolution)
Expand Down
65 changes: 65 additions & 0 deletions R/coord-quickmap.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#' Cartesian coordinates with an aspect ratio approximating mercator projection.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe Mercator?

#'
#' The represenation of a portion of the earth, wich is approximately spherical,
#' onto a flat 2D plane requires a projection. This is what
#' \code{\link{coord_map}} does. These projections account for the fact that the
#' actual length (in km) of one degree of longitude varies between the equator
#' and the pole. Near the equator, the ratio between the lengths of one degree
#' of latitude and one degree of longitude is approximately 1. Near the pole, it
#' is tends towards infinity because the length of one degree of longitude tends
#' towards 0. For regions that span only a few degrees and are not too close to
#' the poles, setting the aspect ratio of the plot to the appropriate lat/lon
#' ratio approximates the usual mercator projection. This is what
#' \code{coord_quickmap} does. With \code{\link{coord_map}} all elements of the
#' graphic have to be projected which is not the case here. So
#' \code{\link{coord_quickmap}} has the advantage of being much faster, in
#' particular for complex plots such as those using with
#' \code{\link{geom_tile}}, at the expense of correctedness in the projection.
#'
#' @export
#' @inheritParams coord_cartesian
#' @examples
#' # ensures that the ranges of axes are equal to the specified ratio by
#' # adjusting the plot aspect ratio
#'
#' if (require("maps")) {
#' # Create a lat-long dataframe from the maps package
#' nz <- map_data("nz")
#' # Prepare a plot of the map
#' nzmap <- ggplot(nz, aes(x=long, y=lat, group=group)) +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spaces around = please

#' geom_polygon(fill="white", colour="black")
#'
#' # Plot it in cartesian coordinates
#' nzmap
#' # With correct mercator projection
#' nzmap + coord_map()
#' # With the aspect ratio approximation
#' nzmap + coord_quickmap()
#' }
#'
#' # Resize the plot to see that the specified aspect ratio is maintained
coord_quickmap <- function(xlim = NULL, ylim = NULL) {
coord(limits = list(x = xlim, y = ylim),
subclass = c("quickmap", "cartesian"))
}

#' @export coord_aspect quickmap
coord_aspect.quickmap <- function(coord, ranges) {
# compute coordinates of center point of map
x.center <- sum(ranges$x.range) / 2
y.center <- sum(ranges$y.range) / 2

# compute distance corresponding to 1 degree in either direction
# from the center
x.dist <- dist_central_angle(x.center+c(-0.5,0.5), rep(y.center,2))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spaces around + and -, and after commas please

y.dist <- dist_central_angle(rep(x.center,2), y.center+c(-0.5,0.5))
# NB: this makes the projection correct in the center of the plot and
# increasingly less correct towards the edges. For regions of reasonnable
# size, this seems to give better results than computing this ratio from
# the total lat and lon span.

# scale the plot with this aspect ratio
ratio <- y.dist / x.dist

diff(ranges$y.range) / diff(ranges$x.range) * ratio
}
51 changes: 51 additions & 0 deletions man/coord_quickmap.Rd
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
% Generated by roxygen2 (4.0.0): do not edit by hand
\name{coord_quickmap}
\alias{coord_quickmap}
\title{Cartesian coordinates with an aspect ratio approximating mercator projection.}
\usage{
coord_quickmap(xlim = NULL, ylim = NULL)
}
\arguments{
\item{xlim}{limits for the x axis}

\item{ylim}{limits for the y axis}
}
\description{
The represenation of a portion of the earth, wich is approximately spherical,
onto a flat 2D plane requires a projection. This is what
\code{\link{coord_map}} does. These projections account for the fact that the
actual length (in km) of one degree of longitude varies between the equator
and the pole. Near the equator, the ratio between the lengths of one degree
of latitude and one degree of longitude is approximately 1. Near the pole, it
is tends towards infinity because the length of one degree of longitude tends
towards 0. For regions that span only a few degrees and are not too close to
the poles, setting the aspect ratio of the plot to the appropriate lat/lon
ratio approximates the usual mercator projection. This is what
\code{coord_quickmap} does. With \code{\link{coord_map}} all elements of the
graphic have to be projected which is not the case here. So
\code{\link{coord_quickmap}} has the advantage of being much faster, in
particular for complex plots such as those using with
\code{\link{geom_tile}}, at the expense of correctedness in the projection.
}
\examples{
# ensures that the ranges of axes are equal to the specified ratio by
# adjusting the plot aspect ratio

if (require("maps")) {
# Create a lat-long dataframe from the maps package
nz <- map_data("nz")
# Prepare a plot of the map
nzmap <- ggplot(nz, aes(x=long, y=lat, group=group)) +
geom_polygon(fill="white", colour="black")

# Plot it in cartesian coordinates
nzmap
# With correct mercator projection
nzmap + coord_map()
# With the aspect ratio approximation
nzmap + coord_quickmap()
}

# Resize the plot to see that the specified aspect ratio is maintained
}