Closed itcarroll closed 5 years ago
The thing that immediately comes to mind for me is that each existing aesthetic has a corresponding scale_
function, e.g. colo[u]r
has scale_colo[u]r_*
.
Would there be something similar to that for the panel
aesthetic?
What would scale_panel_*
functions do?
The arguments for facet_wrap
are presently a combination of scale and label customizations. I think scale_panel
would adopt:
And panellab
(a al xlab, ylab) would get
But I admit, I am fuzzy on the general principle of scale_*
functions.
My 2 cents: I agree specifying facets via aesthetics makes sense. This is what Altair does, I believe. However, I don't see the need to throw out the facet_*()
functions. They could simply be extended to derive faceting instructions from aesthetics in addition to the formula interface and vars()
. I see several arguments for this:
The facet_*()
interface is extremely widely used and needs to be maintained going forward. So whatever changes are made must be compatible with it.
Using scale_panel_*()
instead of facet_*()
seems a bit forced to me. I don't immediately see how things like breaks, limits, titles, transformations map to facets. One could probably make it work somehow but it's not clear that it would be less confusing than what we currently have. I doubt people commonly think of facets in terms of scales.
The general convention in ggplot2 is that the aesthetic mapping by itself doesn't cause things to be drawn. So it's not clear to me that setting faceting aesthetics should do anything unless we also add something like facet_wrap()
or facet_grid()
. And, different faceting mechanism would need different aesthetics (wrap would need one, grid would need two), so it would make sense to have aesthetics that are specific to the facet type used and that get activated only once the facet is added.
@itcarroll Do you think that something like this would be less confusing to your students than what we currently have:
ggplot(mpg, aes(x = displ, y = hwy, facet = class)) +
geom_point() + facet_wrap()
I’m personally very much against this for several reasons. There’s a fundamental difference in specifying the layout of the plot and the visual appearance of graphic elements and I think mixing the two is theoretically inconsistent. Further it seems to me that mixing the two will be much less powerful as it assumes there’s a direct 1-1 mapping of data to panel which is not the case for the provided facets (e.g. with adding margins) and especially not with facets in extensions such as facet_zoom
Reply to @clauswilke's points:
scale_shape_discrete
.+ facet_wrap()
, after I've just said that the x and y axes are part of the aesthetic and apply to any rendered geometry. Would a z axis need a + layout_3D()
layer? (I have no idea how/if ggplot2 already handles a z axes :)@thomasp85 By "layout" do you mean margins and such? If so, I agree that's separate but I disagree that panels should then be considered part of the layout. I think of them as another axis.
Thanks to all for considering! I've made my request and will shut up now, unless there's another question addressed specifically to me.
@thomasp85 I once argued against this too, but this discussion with gadfly's creator eventually convinced me otherwise. In an abstract sense, facets are positioning complex glyphs on a page, where the complex glyph is an entire subplot, and the positioning is (usually) a rectangular layout — subplots are mapped from an abstract space (whatever small multiples mean to the creator) on to (x,y) positions. Thinking of facetting more broadly, one could imagine:
The standard layout of wrap/grid is a special case with a simple layout: bin the plots along a rectangular grid. Margins aren't inconsistent with this perspective: much like complex geoms (boxplot, etc.) that derive/morph new positions/aesthetics from a stat/position/coord, the extra panel would be generated by a meta-stat.
This perspective also opens the way to new concepts such as scaling facets – background colour, size, shape, transparency, etc. which could turn out to be a powerful extension of the grammar (for instance, highlighting a specific panel by setting the alpha of all the others to almost transparent).
Incan get on board with the idea that it is considered a meta-aesthetic, but that is, in my view, another reason why it should live outside of geom aesthetic specification.
For your point about animations I completely agree which is why the frame
aesthetic was removed from the gganimate API and substituted for a more powerful transition_*()
class more in line with the facet function. The other approach was simply too simplistic
this way one could also deal with a hybrid facet_{grid,wrap}
I often want, i.e. facet_grid
with additional per-facet titles. currently this is only hackable via
data <- data.frame(Clust = ..., Rank = ..., Gene = ..., Expr = ..., X = ..., Y = ...)
data_titles <- data %>% group_by(Clust, Rank) %>% summarise(Gene = Gene[[1]])
ggplot() +
geom_point(aes(X, Y, colour = Expr), data) +
geom_text(aes(label = Gene), data_titles, x = Inf, y = Inf, hjust = 1, vjust = 1) +
facet_grid(vars(Clust), vars(Rank))
You could implement this fairly easily in an extension:
library(ggplot2)
facet_aes <- function(facets = NULL, ...) {
wrap <- facet_wrap(facets = vars(dummy), ...)
ggproto("FacetAes", wrap)
}
ggplot_add.FacetAes <- function(object, plot, object_name) {
object$params$facets <- plot$mapping["panel"]
plot$mapping$panel <- NULL
NextMethod()
}
ggplot(mpg, aes(cty, hwy, panel = class)) +
geom_point() +
facet_aes()
Created on 2019-06-17 by the reprex package (v0.2.1)
I now see facets as a special case of x
and y
positioning, but I think this is too major a change to major to ggplot2 at this point in its life cycle.
This old issue has been automatically locked. If you believe you have found a related problem, please file a new issue (with reprex) and link to this issue. https://reprex.tidyverse.org/
I think it is consistent with the grammar of graphics to call the mapping of a variable to a panel an aesthetic. Would it be possible to provide an alternative to
facet_wrap
andfacet_grid
that draws on an additional argument toaes
? I teach ggplot2 in workshops, and have trouble justifying the logic offacet_*
(both the old formula notation and the new use ofvars
). I think it would be more natural to allow apanel
argument toaes
as follows below this example taken from thefacet_wrap
docs.My suggestion is that the identical outcome be achieved with:
The
panel
argument could accept two variables forfacet_grid
behavior, and the remaining customization arguments infacet_*
could be accessed with ascale_panel
andpanellabs
functions.