inverting y-axis for only one of a faceted group you're going to have to use viewports or an approach with facets as I suggested, where you plot the desired panels separately with facets and then combine with inkscape or illustrator. cheers, James |
--
You received this message because you are subscribed to the ggplot2 mailing list.
Please provide a reproducible example: http://gist.github.com/270442
To post: email ggp...@googlegroups.com
To unsubscribe: email ggplot2+u...@googlegroups.com
More options: http://groups.google.com/group/ggplot2
On 10-11-17 11:03 AM, James McCreight wrote:
> Hi Jonathan-
>
> It seems like people want facets to do all sorts of things these days!
>
> according to Hadley's book, page 115:
> "Faceting generates small multiples each showing a different subset of
> the data."
>
> Facets are not intended to be so customizable. Facets do not replace
> viewports. see today's discussion
>
> inverting y-axis for only one of a faceted group
> <http://groups.google.com/group/ggplot2/t/1ce180106d16d946>
> <mailto:ggp...@googlegroups.com>
> To unsubscribe: email ggplot2+u...@googlegroups.com
> <mailto:ggplot2%2Bunsu...@googlegroups.com>
FacetGrid$new <- function(., facets = . ~ ., margins = FALSE, scales = "fixed", space = "fixed", labeller = "label_value", as.table = TRUE, widths = NULL, heights = NULL) {
scales <- match.arg(scales, c("fixed", "free_x", "free_y", "free"))
free <- list(
x = any(scales %in% c("free_x", "free")),
y = any(scales %in% c("free_y", "free"))
)
space <- match.arg(space, c("fixed", "free"))
if (is.formula(facets)) facets <- deparse(facets)
.$proto(
facets = facets, margins = margins,
free = free, space_is_free = (space == "free"),
scales = NULL, labeller = list(labeller), as.table = as.table,
space_widths = widths, space_heights = heights
)
}
FacetGrid$ # Create grobs for each component of the panel guides
add_guides <- function(., data, panels_grob, coord, theme) {
aspect_ratio <- theme$aspect.ratio
# If user hasn't set aspect ratio, and we have fixed scales, then
# ask the coordinate system if it wants to specify one
if (is.null(aspect_ratio) && !.$free$x && !.$free$y) {
xscale <- .$scales$x[[1]]
yscale <- .$scales$y[[1]]
ranges <- coord$compute_ranges(list(x = xscale, y = yscale))
aspect_ratio <- coord$compute_aspect(ranges)
}
if (is.null(aspect_ratio)) {
aspect_ratio <- 1
respect <- FALSE
} else {
respect <- TRUE
}
nr <- nrow(panels_grob)
nc <- ncol(panels_grob)
coord_details <- matrix(list(), nrow = nr, ncol = nc)
for (i in seq_len(nr)) {
for(j in seq_len(nc)) {
scales <- list(
x = .$scales$x[[j]]$clone(),
y = .$scales$y[[i]]$clone()
)
coord_details[[i, j]] <- coord$compute_ranges(scales)
}
}
# Horizontal axes
axes_h <- list()
for(i in seq_along(.$scales$x)) {
axes_h[[i]] <- coord$guide_axis_h(coord_details[[1, i]], theme)
}
axes_h_height <- do.call("max2", llply(axes_h, grobHeight))
axeshGrid <- grobGrid(
"axis_h", axes_h, nrow = 1, ncol = nc,
heights = axes_h_height, clip = "off"
)
# Vertical axes
axes_v <- list()
for(i in seq_along(.$scales$y)) {
axes_v[[i]] <- coord$guide_axis_v(coord_details[[i, 1]], theme)
}
axes_v_width <- do.call("max2", llply(axes_v, grobWidth))
axesvGrid <- grobGrid(
"axis_v", axes_v, nrow = nr, ncol = 1,
widths = axes_v_width, as.table = .$as.table, clip = "off"
)
# Strips
labels <- .$labels_default(.$shape, theme)
strip_widths <- llply(labels$v, grobWidth)
strip_widths <- do.call("unit.c", llply(1:ncol(strip_widths),
function(i) do.call("max2", strip_widths[, i])))
stripvGrid <- grobGrid(
"strip_v", t(labels$v), nrow = nrow(labels$v), ncol = ncol(labels$v),
widths = strip_widths, as.table = .$as.table
)
strip_heights <- llply(labels$h, grobHeight)
strip_heights <- do.call("unit.c", llply(1:nrow(strip_heights),
function(i) do.call("max2", strip_heights[i, ])))
striphGrid <- grobGrid(
"strip_h", t(labels$h), nrow = nrow(labels$h), ncol = ncol(labels$h),
heights = strip_heights
)
# Add background and foreground to panels
panels <- matrix(list(), nrow=nr, ncol = nc)
for(i in seq_len(nr)) {
for(j in seq_len(nc)) {
fg <- coord$guide_foreground(coord_details[[i, j]], theme)
bg <- coord$guide_background(coord_details[[i, j]], theme)
panels[[i,j]] <- grobTree(bg, panels_grob[[i, j]], fg)
}
}
if(.$space_is_free) {
size <- function(y) unit(diff(y$output_expand()), "null")
panel_widths <- do.call("unit.c", llply(.$scales$x, size))
panel_heights <- do.call("unit.c", llply(.$scales$y, size))
} else {
if (!is.null(.$space_widths)) {
panel_widths <- do.call("unit.c", lapply(.$space_widths, function(x)unit(x, "null")))
} else {
panel_widths <- unit(1, "null")
}
if (!is.null(.$space_heights)) {
panel_heights <- do.call("unit.c", lapply(.$space_heights, function(x)unit(x, "null")))
} else {
panel_heights <- unit(1 * aspect_ratio, "null")
}
}
panelGrid <- grobGrid(
"panel", t(panels), ncol = nc, nrow = nr,
widths = panel_widths, heights = panel_heights, as.table = .$as.table,
respect = respect
)
# Add gaps and compute widths and heights
fill_tl <- spacer(nrow(labels$h), 1)
fill_tr <- spacer(nrow(labels$h), ncol(labels$v))
fill_bl <- spacer(1, 1)
fill_br <- spacer(1, ncol(labels$v))
all <- rbind(
cbind(fill_tl, striphGrid, fill_tr),
cbind(axesvGrid, panelGrid, stripvGrid),
cbind(fill_bl, axeshGrid, fill_br)
)
# theme$panel.margin, theme$panel.margin
# from left to right
hgap_widths <- do.call("unit.c", compact(list(
unit(0, "cm"), # no gap after axis
rep.unit2(theme$panel.margin, nc - 1), # gap after all panels except last
unit(rep(0, ncol(stripvGrid) + 1), "cm") # no gap after strips
)))
hgap <- grobGrid("hgap",
ncol = ncol(all), nrow = nrow(all),
widths = hgap_widths,
)
# from top to bottom
vgap_heights <- do.call("unit.c", compact(list(
unit(rep(0, nrow(striphGrid) + 1), "cm"), # no gap after strips
rep.unit2(theme$panel.margin, nr - 1), # gap after all panels except last
unit(0, "cm") # no gap after axis
)))
vgap <- grobGrid("vgap",
nrow = nrow(all), ncol = ncol(all) * 2,
heights = vgap_heights
)
rweave(cweave(all, hgap), vgap)
}
qplot(mpg, wt, data=mtcars) + facet_grid(cyl ~ vs, widths=c(1,2), heights=c(1,1,3))
Jonathan, I couldnt agree more with your points! I'd love to see the functionality you envision. Takahashi, thanks for pointing the way.If people choose to hack on facet and could put all their codes in a convenient place, that would be tremendous.
On Wed, Nov 17, 2010 at 6:02 PM, James McCreight <mccr...@colorado.edu> wrote:Jonathan, I couldnt agree more with your points! I'd love to see the functionality you envision. Takahashi, thanks for pointing the way.If people choose to hack on facet and could put all their codes in a convenient place, that would be tremendous.the ggExtra package (googlecode, R-forge) was created with this idea in mind. I'd welcome any contribution, any time.Note that there have been several partial answers to the query of aligning plot axes using Grid viewports, some of them are on the list archive, and a basic version is in the ggExtra package -- align.plots().baptiste
I would consider this approach next time i need something new from facet, instead of the inkscape illustrator approach. I already have a list of things from the past and there are 2 already today.On Wed, Nov 17, 2010 at 9:47 AM, Kohske Takahashi <takahash...@gmail.com> wrote:
hi,probably it is easy to hack. I attached an ad-hoc hack and patch below.actually I agree with James and concept of ggplot2, because modifying spaces of facet is confusing for readers and makes difficult to compare between subsets.but also I understand such function is useful in some case for pragmatic reason.