-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Geoms and scales: default settings in theme #2239
Comments
I think we can do this for the next major release of ggplot2 (i.e. this can be a project for my next summer intern). The basic implementation is much simpler than I'd feared; the work will mostly be carefully considering which theme properties we need and then performing a routine transformation for each geom. (We'll probably also need to use a SE variant of |
Sounds great! As themes grow in scope, I wonder if one could also consider developing an alternative syntax for them, based on css. (I'm thinking of the way d3.js often uses css to set default properties, although that's a bit inconsistent because of the css vs svg attributes mess). |
I was thinking about the same issue the last few days, but I'd like to propose a different angle of attack: Is there any reason why the theme can't simply store a list of default scales? Something like |
@clauswilke this seems orthogonal to the original issue. I agree that it would be nice to have default colour palettes associated with the theme (ggthemes comes to mind), but in my view (as I've argued before) the issue is that |
Just to clarify on this one issue:
I'm suggesting to register the default scales with the theme, not make the theme the preferred way of changing scales. My proposal would change virtually nothing for existing ggplot2 code, other than that |
I understood your proposal but I still think it'd be awkward and foreign to the ggplot2 framework to start putting things like default scales in the theme. Note that geoms have defaults too: point shape, colour (and also stat, position, etc.). This proposal was to set the default visual aspects of geoms (unset and unmapped aesthetics), which is independent of the grammar. Scales, in their function, are part of the grammar, but a specific colour palette (within a class – continuous/discrete/gradient) should not have to be. |
@clauswilke would you mind moving the discussion of associating default scales with a theme to another issue? I think it might be a good idea, but it is largely orthogonal to this issue. |
@dpseidel I think the place to start is to figure out what are the primary geom defaults that need to go in the theme - i.e. points and lines have different sizes, but are there more variations? It would be useful to have a table with aesthetics in the columns, geoms in the rows, and the default values in the cells. You should be able to automate most of it starting from: geom_names <- apropos("^Geom", ignore.case = FALSE)
geoms <- mget(geom_names, env = asNamespace("ggplot2"))
lapply(geoms, function(x) x$default_aes) |
a while back it looked something like this – presumably somewhat different now |
I've filed a new issue specifically about default scales in themes (#2691). |
So I have pulled together a list of the current defaults and made my first attempt at an updated hack-- mostly for the benefit of my own understanding of the underpinnings of ggplot's internals. By adding a new theme element After looking over the table of defaults and sorting it some into groups of similarities, it's clear that first and foremost the important defaults to be able to tie to theme are |
From a high-level perspective, my personal inclination would be for a system that uses inheritance to define harmonious and consistent defaults within a theme that "scale" most elements. In the spirit of What I have in mind is a "foreground" (fg) and a "background" (bg) top-level setting, like Beamer themes, and specific theme children would build from those for their own shade, e.g. title.text would use I would also re-advocate for consideration of a CSS parser + interpreter to define themes going forward (perhaps in the long-term). It'd be quite nice to use this extensible and widespread format, well-suited for the description of cascading styles. Since more and more R graphics target web-based output (plotly, svg, d3, vega, etc) this would be a natural way to specify fonts, colours, margins, even layout maybe one day. Anyway, this is kind of tangential to the discussion, but I see that Claus came up with the same idea recently re text limitations in grid. PS: I wrote this with the usual theme defaults in mind, but I think it applies to geom defaults as well, for a consistent look (the archetypical example being a black-background theme: one would want grid lines, text, but also point outlines to default to white, otherwise they become invisible). |
I'm all for going CSS. I think it's the correct long-term vision. The one issue that I ran into and couldn't immediately resolve a few months ago is that there doesn't seem to be a decent CSS parser available for R, comparable to, for example, xml2 for parsing html. I wrote some regular expressions for simplistic CSS parsing, but it doesn't do the inheritance part of CSS, it just parses key-value pairs. |
I think css is way way way too complicated. Maybe a css like DSL would be ok, but it would be a huge amount of work to develop the parser and specification. I don’t think using css is worth the implementation cost, especially given that the current theme system isn’t that bad. The goal here is to find a simple way of controlling geom defaults from the theme, not a complete overhaul of the theme system. |
I also failed to find one, but it's probably a case where there's little sense in reinventing the wheel: I don't know this area but R seems to have good support for seamless embedded javascript/html engines (V8?), so I imagine leveraging their functionality by interfacing with R would be the most robust and straight-forward approach. Maybe have the tool produce a json AST, then converted to a data.frame or nested list. |
@hadley I think the two aren't mutually-exclusive: the CSS subset idea is more of a long-term, alternative spec, that could be parsed as an AST and then converted into a ggplot2 theme object. I agree that right now it would seem a serious overkill, but going forward I imagine grid will need a successor, and IMO it would make sense to start thinking of a broader context for R graphics, with modern accepted technologies and formats (ie thinking in terms of, and leveraging, powerful tooks like css and svg attributes). |
@hadley Yes, exactly what @baptiste is saying. @dpseidel should continue doing exactly what she is doing. We're just trying to formulate a vision of where things could go in the future. Maybe off-topic, but also broadly related. I arrived at HTML/CSS from the perspective of wanting to add text labels that can change formatting half-way through, e.g. with one word in italics or in a different color. We could invent a new R DSL for that, just like plotmath, but I think going with existing standards is better. And also, I think there is a smooth transition from the current theme system to HTML/CSS that keeps the current theme system relevant all the way to the end:
|
I think moving away from DSLs implemented in R (internal dsls) to DSLs implemented in another language (external dsls) is a bad idea, especially given the poor match between the very general needs of HTML and CSS, and the specific needs of a visualisation system. It feels very "untidy" to me. |
... That last comment doesn't seem well reasoned to me. HTML and CSS are literally for purposes of visualisation. You could argue that they have wider scope for other reasons, but just being a visualisation system doesn't necessarily imply more specific needs than another visualisation system. It's a bit of a nitpick though, as I agree that adding another layer of syntax is not probably not helpful. I mean... if that route were followed through with completely, then why not write a d3 generator instead of using ggplot2 in the first place? |
This idea has been floated around multiple times but I'll raise it again. Currently, themes do not affect the geom properties, such as point and line colour, etc. Scales, in particular colour and fill, suffer the same issue.
Users who wish to use a specific theme – theme_dark() is a striking example – end up having to change the geom and/or scale defaults. A consistent yet original look, such as a company's brand, may require to set default colour schemes for discrete and continuous scales.
These two steps currently require adding multiple manual parameters to each plot, or fiddling around with the awkward combination of
set_geom_defaults()
andscale_colour_discrete <- scale_colour_brewer
.The suggestion made here is to consider default aesthetics an integral part of the grammar – they're not mapped to data (unless they are), but should be consistent with the overall look of the theme. Themes have gained in consistency with
rel()
and inheritance, but at the moment setting a dark background will make points invisible: not a great default behaviour.Lattice, as well as Julia's Gadfly, seem to have followed this line of thought to include geom defaults in the theme description. Beamer themes define default colour schemes to be inherited by slide elements.
A proof-of principle, setting point colours to default to the plot title's colour (an existing theme element, for simplicity), was implemented here. (Note: the use of complex numbers is just for curiosity – it would correspond to something like
waiver()
in the standard ggplot2 way of dealing with values that are to be resolved just before rendering.The text was updated successfully, but these errors were encountered: