theme-ing up

458 views
Skip to first unread message

baptiste auguie

unread,
Jul 9, 2011, 6:59:05 PM7/9/11
to ggplot2
Dear list,

I would like to propose two ideas re: themes.

First, the addition of an ellipsis parameter ..., which would be used
to overwrite any of the settings of a particular theme. As an example,

theme_bw2 <- function (base_size = 12, base_family = "", ...){

modifyList(theme_bw(base_size = base_size, base_family =
base_family), list(...))

}

(p <-
qplot(mpg, wt, data=mtcars) +
theme_bw2(18, panel.grid.major=theme_line(colour="grey90", linetype=2)) )

I find it more intuitive to have it all wrapped in a single call to
theme_xxx() rather than subsequent changes with opts(...). Further,
defining all themes in this manner with respect to the default theme
(theme_grey()) would signal more clearly which parameters are altered
from one theme to the other.

Second, it could be nice to use some user feedback to fine-tune and
extend the set of pre-defined themes that ship with ggplot2. What
opts() do we use most of the time? What groups of options work well
together and are used by many people? Have people defined themes that
match the templates of powerpoint/beamer presentations? Specific
options for particular journals?
Perhaps a good way to find out is by sharing such ideas. For
convenience I started a new page on the ggplot2 wiki <
https://github.com/hadley/ggplot2/wiki/Themes > with two themes that I
have to source() repeatedly.

_____________________

## minimalistic theme to save ink, and make E. Tufte happy

theme_minimal <- function (base_size = 12, base_family = "")
{
structure(list(axis.line = theme_blank(), axis.text.x =
theme_text(family = base_family,
size = base_size * 0.8, lineheight = 0.9, vjust = 1),
axis.text.y = theme_text(family = base_family, size = base_size *
0.8, lineheight = 0.9, hjust = 1), axis.ticks =
theme_segment(colour = "black",
size = 0.2), axis.title.x = theme_text(family = base_family,
size = base_size, vjust = 1), axis.title.y =
theme_text(family = base_family,
size = base_size, angle = 90, vjust = 0.5),
axis.ticks.length = unit(0.3,
"lines"), axis.ticks.margin = unit(0.5, "lines"),
legend.background = theme_rect(colour = NA), legend.key =
theme_rect(colour = NA),
legend.key.size = unit(1.2, "lines"), legend.key.height = NA,
legend.key.width = NA, legend.text = theme_text(family = base_family,
size = base_size * 0.8), legend.text.align = NA,
legend.title = theme_text(family = base_family, size = base_size *
0.8, face = "bold", hjust = 0), legend.title.align = NA,
legend.position = "right", legend.direction = "vertical",
legend.box = NA, panel.background = theme_rect(fill = "white",
colour = NA), panel.border = theme_rect(fill = NA,
colour = "grey90"), panel.grid.major = theme_line(colour =
"grey90",
size = 0.2), panel.grid.minor = theme_line(colour = "grey98",
size = 0.5), panel.margin = unit(0.25, "lines"),
strip.background = theme_rect(fill = NA, colour = NA),
strip.text.x = theme_text(family = base_family, size = base_size *
0.8), strip.text.y = theme_text(family = base_family,
size = base_size * 0.8, angle = -90), plot.background =
theme_rect(colour = NA),
plot.title = theme_text(family = base_family, size = base_size *
1.2), plot.margin = unit(c(1, 1, 0.5, 0.5), "lines")),
class = "options")
}

p + theme_minimal()

## options to expand the plotting area to the full viewport

opts_fullframe <- function(){

structure(list(legend.position = "none",
panel.background = theme_blank(),
panel.grid.major = theme_blank(),
panel.grid.minor = theme_blank(),
panel.margin = unit(0,"null"),
plot.margin = rep(unit(0,"null"),4),
axis.ticks = theme_blank(),
axis.text.x = theme_blank(),
axis.text.y = theme_blank(),
axis.title.x = theme_blank(),
axis.title.y = theme_blank(),
axis.ticks.length = unit(0,"null"),
axis.ticks.margin = unit(0,"null")), class = "options")

}

p + opts_fullframe()

Looking forward to your comments on either proposal.

Best regards,

baptiste

Bryan Hanson

unread,
Jul 9, 2011, 9:53:00 PM7/9/11
to baptiste auguie, ggplot2
I think this is a great idea.

My contribution is very simple, probably not worth much, but when I make graphs for poster presentations, I iike to add + theme_gray(base_size = 18) so the text stands out enough and tracks well with the text on the poster. It's really easy to forget this, expecially when proofing poster on the screen where you often blow them up to check details.

Bryan
****************
Prof. Bryan Hanson
Dept of Chemistry & Biochemistry
DePauw University
Greencastle IN 46135 USA

> --
> 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

Brian Diggs

unread,
Jul 11, 2011, 6:07:39 PM7/11/11
to ggplot2, baptiste auguie
On 7/9/2011 3:59 PM, baptiste auguie wrote:
> Dear list,
>
> I would like to propose two ideas re: themes.
>
> First, the addition of an ellipsis parameter ..., which would be used
> to overwrite any of the settings of a particular theme. As an example,
>
> theme_bw2<- function (base_size = 12, base_family = "", ...){
>
> modifyList(theme_bw(base_size = base_size, base_family =
> base_family), list(...))
>
> }
>
> (p<-
> qplot(mpg, wt, data=mtcars) +
> theme_bw2(18, panel.grid.major=theme_line(colour="grey90", linetype=2)) )
>
> I find it more intuitive to have it all wrapped in a single call to
> theme_xxx() rather than subsequent changes with opts(...). Further,
> defining all themes in this manner with respect to the default theme
> (theme_grey()) would signal more clearly which parameters are altered
> from one theme to the other.

I like this as well. However, one thing that I occasionally bump into
that this would make even worse (or rather, more "surprising") has to do
with theme_text's. Using the base_size argument to a theme is a great
way set the scale of all the text. However, if I also want to make some
other changes to some text (rotating, say), I have to remember to reset
the size in that call (usually looking at the theme_gray() call to see
how the size of it relates to base_size.

For example:

p <- qplot(mpg, wt, data=mtcars)

# Increase the text size and also rotate the y axis title
p + theme_bw(base_size = 18) + opts(axis.title.y=theme_text(angle=0))
# or using theme_bw2 proposed above to
# increase the text size and rotate the y axis title
p + theme_bw2(18, axis.title.y=theme_text(angle=0))
# This resets the text size (and family) to the default from
# theme_text (plain and size 10). You need to do
p + theme_bw2(18, axis.title.y=theme_text(size=18,angle=0))
# This involves specifying the size multiple times and in
# multiple places. Even harder
# Increase the text size and rotate the y axis labels
p + theme_bw2(18, axis.text.y=theme_text(angle=90))
# should really be
p + theme_bw2(18, axis.text.y=theme_text(size=0.8*18, angle=90))
# to keep the size from being changed.


Unfortunately, this would be a hard change, I think. Because then all
themes are iterative updates to each part of the theme separately.
Defaults become not function argument defaults, but the first layer of
inheritance. aes behaves something like this now.

These examples are meant more as a caution. It is already easy to
forget to reset the size, and if it was all in one call, it would be
even easier to forget (since you already specified it in the function call).

> Second, it could be nice to use some user feedback to fine-tune and
> extend the set of pre-defined themes that ship with ggplot2. What
> opts() do we use most of the time? What groups of options work well
> together and are used by many people? Have people defined themes that
> match the templates of powerpoint/beamer presentations? Specific
> options for particular journals?
> Perhaps a good way to find out is by sharing such ideas. For
> convenience I started a new page on the ggplot2 wiki<
> https://github.com/hadley/ggplot2/wiki/Themes> with two themes that I
> have to source() repeatedly.

I pretty much use theme_bw exclusively. But every one in awhile I need
the fullframe one, and have to hunt down each part of it; thanks for
putting it in one place. I can see journal specific ones being useful
(organizational specific themes are probably needed as well, but are
only of interest inside that org.)


--
Brian S. Diggs, PhD
Senior Research Associate, Department of Surgery
Oregon Health & Science University

baptiste auguie

unread,
Jul 11, 2011, 7:46:15 PM7/11/11
to Brian Diggs, ggplot2, baptiste auguie
Hi Brian,

Interesting, thanks for bringing this up. I wonder what led to the
design decision of mapping size to gpar()$fontsize rather than to
gpar()$cex for this purpose. That would still leave the problem of
base_family, though.
That being said, I'm pretty sure this is only a technical detail that
could be overcome, if the basic concept proved popular.

Cheers,

baptiste

David Kahle

unread,
Jul 11, 2011, 7:46:41 PM7/11/11
to baptiste auguie, ggplot2
I've also just added a theme to the wiki I used a while back called theme_black.  it is nice for black background presentations, but you usually have to change colour aesthetics to make things visible.

theme_black <- function (base_size = 12){
  structure(list(
    axis.line = theme_blank(), 
    axis.text.x = theme_text(size = base_size * 0.8, colour = 'white', lineheight = 0.9, vjust = 1), 
    axis.text.y = theme_text(size = base_size * 0.8, colour = 'white', lineheight = 0.9, hjust = 1), 
    axis.ticks = theme_segment(colour = "white", size = 0.2), 
    axis.title.x = theme_text(size = base_size, colour = 'white', vjust = 1), 
    axis.title.y = theme_text(size = base_size, colour = 'white', angle = 90, vjust = 0.5), 
    axis.ticks.length = unit(0.3, "lines"), 
    axis.ticks.margin = unit(0.5, "lines"), 
    legend.background = theme_rect(colour = NA), 
    legend.key = theme_rect(colour = "white", fill = 'black'), 
    legend.key.size = unit(1.2, "lines"), 
    legend.key.height = NA
    legend.key.width = NA,     
    legend.text = theme_text(size = base_size * 0.8, colour = 'white'), 
    legend.title = theme_text(size = base_size * 0.8, face = "bold", hjust = 0, colour = 'white'), 
    legend.position = "right"
    legend.text.align = NA
    legend.title.align = NA
    legend.direction = "vertical"
    legend.box = NA,    
    panel.background = theme_rect(fill = "black", colour = NA), 
    panel.border = theme_rect(fill = NA, colour = "white"), 
    panel.grid.major = theme_line(colour = "grey20", size = 0.2), 
    panel.grid.minor = theme_line(colour = "grey5", size = 0.5), 
    panel.margin = unit(0.25, "lines"), 
    strip.background = theme_rect(fill = "grey30", colour = "grey10"), 
    strip.text.x = theme_text(size = base_size * 0.8, colour = 'white'), 
    strip.text.y = theme_text(size = base_size * 0.8, colour = 'white', angle = -90), 
    plot.background = theme_rect(colour = 'black', fill = 'black'), 
    plot.title = theme_text(size = base_size * 1.2), 
    plot.margin = unit(c(1, 1, 0.5, 0.5), "lines")
  ), class = "options")
}

qplot(1:10, 1:10, colour = I('white')) + theme_black()
qplot(mpg, wt, data = mtcars, colour = factor(cyl)) + theme_black()


Cheers
david.



David Kahle

unread,
Jul 12, 2011, 12:55:52 AM7/12/11
to baptiste auguie, Brian Diggs, ggplot2
By request I also added the theme_nothing to the site; it's
essentially the fullframe theme with extended margins (maybe just an
omission from fullframe?).

Cheers
d.

baptiste auguie

unread,
Jul 12, 2011, 1:01:26 AM7/12/11
to David Kahle, ggplot2
Indeed, I forgot the margins. We should merge the two, I guess.


Thanks,

baptiste

Claudia Beleites

unread,
Jul 12, 2011, 6:23:48 AM7/12/11
to ggp...@googlegroups.com
I entered two (three) more variants to the Wiki that I frequently use.
Feel free to change/rename them.

Claudia

>>>> Oregon Health& Science University


>>>>
>>>> --
>>>> 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
>>>>
>>>
>>> --
>>> 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
>>
>>
>
> --
> 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


--
Claudia Beleites
Spectroscopy/Imaging
Institute of Photonic Technology
Albert-Einstein-Str. 9
07745 Jena
Germany

email: claudia....@ipht-jena.de
phone: +49 3641 206-133
fax: +49 2641 206-399


Michael Cheng

unread,
Jul 15, 2011, 5:51:29 AM7/15/11
to ggplot2
On Sun, Jul 10, 2011 at 8:59 AM, baptiste auguie <bapt...@googlemail.com> wrote:
Second, it could be nice to use some user feedback to fine-tune and
extend the set of pre-defined themes that ship with ggplot2. What
opts() do we use most of the time? What groups of options work well
together and are used by many people? Have people defined themes that
match the templates of powerpoint/beamer presentations? Specific
options for particular journals?
Perhaps a good way to find out is by sharing such ideas. For
convenience I started a new page on the ggplot2 wiki <
https://github.com/hadley/ggplot2/wiki/Themes > with two themes that I
have to source() repeatedly.

This is a fantastic idea! If each theme could be paired with an example plot using that theme it would work wonders to show the flexibility of ggplot. 

Mike.

Brian Diggs

unread,
Jul 15, 2011, 1:37:13 PM7/15/11
to ggp...@googlegroups.com

That would be good. I did something similar with the labeller wiki page
(https://github.com/hadley/ggplot2/wiki/labeller), but it was harder
than I thought it should have been. Most wikis allow a page which is an
image which can be embedded in a page. I couldn't see how to do that
with the wiki on GitHub. You can link to a file in the repository
(either the project or wiki repository), but not having write
permissions on that I couldn't get the image there. What I ended up
doing was creating a repository of my own which contained the images
which could then be displayed inline. I'm open to better/smoother
suggestions.

For images exploring theme, it may also be worthwhile to somehow
indicated where the edge of the image is. Maybe post-processing it to
add a border (described as a guide so people realize it is not part of
the image). This is probably most useful for the minimal theme.

Hadley Wickham

unread,
Jul 15, 2011, 2:01:43 PM7/15/11
to Brian Diggs, ggp...@googlegroups.com
> That would be good.  I did something similar with the labeller wiki page
> (https://github.com/hadley/ggplot2/wiki/labeller), but it was harder than I
> thought it should have been.  Most wikis allow a page which is an image
> which can be embedded in a page. I couldn't see how to do that with the wiki
> on GitHub.  You can link to a file in the repository (either the project or
> wiki repository), but not having write permissions on that I couldn't get
> the image there.  What I ended up doing was creating a repository of my own
> which contained the images which could then be displayed inline. I'm open to
> better/smoother suggestions.

Probably the easiest way (eventually) would be to make an R script
that could take the plot commands and automatically build the
html/markdown page.

Hadley


--
Assistant Professor / Dobelman Family Junior Chair
Department of Statistics / Rice University
http://had.co.nz/

Brian Diggs

unread,
Jul 15, 2011, 2:29:47 PM7/15/11
to hadley wickham, ggplot2
On 7/15/2011 11:01 AM, Hadley Wickham wrote:
>> That would be good. I did something similar with the labeller wiki page
>> (https://github.com/hadley/ggplot2/wiki/labeller), but it was harder than I
>> thought it should have been. Most wikis allow a page which is an image
>> which can be embedded in a page. I couldn't see how to do that with the wiki
>> on GitHub. You can link to a file in the repository (either the project or
>> wiki repository), but not having write permissions on that I couldn't get
>> the image there. What I ended up doing was creating a repository of my own
>> which contained the images which could then be displayed inline. I'm open to
>> better/smoother suggestions.
>
> Probably the easiest way (eventually) would be to make an R script
> that could take the plot commands and automatically build the
> html/markdown page.
>
> Hadley

Effectively a weave/noweb approach that has either HTML or markdown as
its output. But the problem is still where is it (it=original source
document)?

You could put it in the git repository that is the source of the wiki on
GitHub. Then the markdown files can be generated from a cloned version
of the repository. But there is still the problem that write access is
limited back to the main site.

If it is elsewhere, then it is further disconnected from the core sources.

In any scenario, the examples need to be regenerated periodically, at
least with each new release. This isn't as automatic as a vignette is.

That said, any of these is still a step in the right direction compared
to the script generating the figures which is detached from the actual
page they are being shown on (which is what I'm using now).

baptiste auguie

unread,
Jul 15, 2011, 7:29:24 PM7/15/11
to Brian Diggs, ggplot2
One option might be to use a web service like http://imgur.com/ (for
which there is an R package facilitating the upload, I believe).

Best,

baptiste

baptiste auguie

unread,
Jul 15, 2011, 8:04:45 PM7/15/11
to Brian Diggs, ggplot2
I've played with some code to facilitate the comparison between themes:

source("http://ggextra.googlecode.com/svn/trunk/inst/tests/themes.r")

which does the following,

themes.list <- list("theme_grey", "theme_bw", "theme_minimal" , "theme_black" ,
"theme_fullframe")

mdf <- data.frame(x <- seq(0, 10), y=rnorm(x),
f=factor(rep(letters[1:2], each=3, length=length(x))))

p <- qplot(x, y, data=mdf, colour=f, geom=c("line", "point"), facets=f~.)

all.themes <- lapply(themes.list,
function(.t) {gTree(children=gList(ggplotGrob(p +
get(.t)()),
rectGrob()))})

library(gridExtra)
library(imguR)

imguR(width=10, height=10)
do.call(grid.arrange, all.themes)
cat(dev.off())


The result at the following url: http://imgur.com/9ZqFW

It looks like some of the proposed themes are not very good with facets.

Cheers,

baptiste

Bryan Hanson

unread,
Jul 16, 2011, 4:08:59 PM7/16/11
to ggplot2
OK, here I am replying to my own suggestion!

I'm trying to build a theme_poster with larger base_size, and larger
point sizes and line widths. Here's what I've come up with. Although
it is patterned on the themes on the wiki, the base_size argument
seems to be ignored. Also, is there a better way (i.e., temporary) to
increase point sizes and line widths than changing the defaults? I
know the structure() is empty: I've tried moving the base_size into
there several ways, all of which are ignored.

TIA Bryan

theme_poster <- function(base_size = 18) {
update_geom_defaults("point", aes(size = 5))
update_geom_defaults("line", aes(size = 2))
structure(list(
), class = "options")
}

df <- data.frame(x = rnorm(10), y = rnorm(10))
p1 <- qplot(x = x, y = y, data = df, geom = c("point", "line"), main =
"Test Plot")
print(p1)

p2 <- p1 + theme_poster()
print(p2)

baptiste auguie

unread,
Jul 16, 2011, 5:46:07 PM7/16/11
to Bryan Hanson, ggplot2
I once started a similar discussion re: themes and geom defaults,

http://groups.google.com/group/ggplot2/browse_thread/thread/a3df8a0d1ee335fb?tvc=2&q=theme

I'm not sure whether things have evolved on that side since then.

baptiste

baptiste auguie

unread,
Jul 16, 2011, 7:40:30 PM7/16/11
to Claudia Beleites, ggp...@googlegroups.com
Hi Claudia,

I've taken the liberty to wrap your lists of options into function()s,
so that I could generate programmatically a graphic for the page with
all current themes. I wonder if we should simplify the code of the
other themes using the modifyList() approach as well.

Best,

baptiste

baptiste auguie

unread,
Jul 16, 2011, 7:57:50 PM7/16/11
to Hadley Wickham, Brian Diggs, ggp...@googlegroups.com
On Sat, Jul 16, 2011 at 6:01 AM, Hadley Wickham <had...@rice.edu> wrote:
>> That would be good.  I did something similar with the labeller wiki page
>> (https://github.com/hadley/ggplot2/wiki/labeller), but it was harder than I
>> thought it should have been.  Most wikis allow a page which is an image
>> which can be embedded in a page. I couldn't see how to do that with the wiki
>> on GitHub.  You can link to a file in the repository (either the project or
>> wiki repository), but not having write permissions on that I couldn't get
>> the image there.  What I ended up doing was creating a repository of my own
>> which contained the images which could then be displayed inline. I'm open to
>> better/smoother suggestions.
>
> Probably the easiest way (eventually) would be to make an R script
> that could take the plot commands and automatically build the
> html/markdown page.
>

An alternative might be to have the R code wrapped in special tags,
and use e.g. the brew package to extract and run the code. I have
often thought there was a case for the creation of a 'wiki' R package
that would facilitate these tasks for github and googlecode wikis,
using perhaps brew/ascii/test_that. You'd store wiki pages with
embedded R code in a directory (possibly even part of an R package);
the wiki package would extract the code, run/test it, include the
results (images, tables, etc.) in the appropriate format, and commit
the changes. That would result in reproducible (and source-able)
wikis, essentially.

All the best,

baptiste


PS: by the way, Hadley, any thoughts re the few questions that came up
in this thread,

- choice of mapping geom_text size to fontsize as opposed to cex?

- using modifyList() to specify the changes to themes?

- should some of these themes/variations be included in ggplot2?

- possibility to specify default geom settings along with a theme?

> Hadley
>
>
> --
> Assistant Professor / Dobelman Family Junior Chair
> Department of Statistics / Rice University
> http://had.co.nz/
>

Claudia Beleites

unread,
Jul 18, 2011, 1:42:19 AM7/18/11
to baptiste auguie, ggp...@googlegroups.com
Dear Baptiste,

> I've taken the liberty to wrap your lists of options into function()s,
> so that I could generate programmatically a graphic for the page with
> all current themes.

Thanks.

> I wonder if we should simplify the code of the
> other themes using the modifyList() approach as well.

It seemed to me the easiest way to concentrate on what is changing (and
to show which other theme it is similar to).

Best,

Claudia

Hadley Wickham

unread,
Jul 18, 2011, 9:42:55 AM7/18/11
to baptiste auguie, Brian Diggs, ggp...@googlegroups.com
> - choice of mapping geom_text size to fontsize as opposed to cex?

cex makes many things much more difficult because you can no longer
figure out (e.g.) how wide the axes viewport needs to be, unless you
know the complete sequence of gTrees/viewports in which it will be
embedded.

> - using modifyList() to specify the changes to themes?

Yes, that's a good idea.

> - should some of these themes/variations be included in ggplot2?

I'd be happy to do that.

> - possibility to specify default geom settings along with a theme?

That's probably another version out (i.e. not until next summer). You
can see some thoughts I had in the layers package -
https://github.com/hadley/layers/blob/master/R/aesthetics-defaults.r.
The layers package is where I've been collecting thoughts about how
the next iteration of layers (geoms, stats and position adjustments)
should work.

Hadley Wickham

unread,
Jul 18, 2011, 9:51:43 AM7/18/11
to baptiste auguie, Brian Diggs, ggp...@googlegroups.com
>> - possibility to specify default geom settings along with a theme?
>
> That's probably another version out (i.e. not until next summer).  You
> can see some thoughts I had in the layers package -
> https://github.com/hadley/layers/blob/master/R/aesthetics-defaults.r.
> The layers package is where I've been collecting thoughts about how
> the next iteration of layers (geoms, stats and position adjustments)
> should work.

I should mention the big challenge with modifying default geom
settings is that they're currently set at the time the geom is
created, where theme settings only come into affect when the plot is
rendered. This means that for themes to affect geoms, I need to make
quite a few changes to the pipeline.

Bryan Hanson

unread,
Jul 18, 2011, 10:03:28 AM7/18/11
to Hadley Wickham, baptiste auguie, Brian Diggs, ggp...@googlegroups.com
Thanks for the follow-up Hadley. It sounds like the method I'm using for theme_poster is the most straightforward for the time being. I'll also create one which restores the default settings as well.

theme_poster <- function(base_size = 24) {
update_geom_defaults("point", aes(size = 3))


update_geom_defaults("line", aes(size = 2))
structure(list(
), class = "options")
}

If anyone sees why the base_size in the function above is ignored, I'd appreciate it.

Thanks, Bryan

Brian Diggs

unread,
Jul 18, 2011, 3:52:47 PM7/18/11
to Bryan Hanson, ggplot2
On 7/18/2011 7:03 AM, Bryan Hanson wrote:
> Thanks for the follow-up Hadley. It sounds like the method I'm using
> for theme_poster is the most straightforward for the time being. I'll
> also create one which restores the default settings as well.
>
> theme_poster<- function(base_size = 24) {
> update_geom_defaults("point", aes(size = 3))
> update_geom_defaults("line", aes(size = 2))
> structure(list(
> ), class = "options")
> }
>
> If anyone sees why the base_size in the function above is ignored, I'd appreciate it.

Well, base_size doesn't do anything because you don't do anything with
it. If you look at theme_bw, base_size appears in the theme_text's. If
you pass it on to another theme which uses the base_size, then you will
see an effect.

theme_poster <- function(base_size = 24) {
update_geom_defaults("point", aes(size = 3))
update_geom_defaults("line", aes(size = 2))

theme_grey(base_size)
}

Now the update_geom_defaults calls are just being used for their side
effects, and it works because theme_poster is called before the geom
defaults are used (in the rendering stage). But it isn't isolated to
that theme call, so you definitely need a function to restore the
defaults (or be happy with the new defaults after the first theme_poster
call). I'd pull those out into a pair of functions that get wrapped
around your plotting:

set_poster_defaults <- function() {


update_geom_defaults("point", aes(size = 3))
update_geom_defaults("line", aes(size = 2))
}

unset_poster_defaults <- function() {
update_geom_defaults("point", aes(size = 2))
update_geom_defaults("line", aes(size = 0.5))
}

theme_poster <- function(base_size = 24) {

theme_grey(base_size)
}

Then theme_poster doesn't do anything but set the base_size (although by
default, so that is something), so you could just use theme_gray(24)
instead.

Your example (from elsewhere in the thread) then looks like:

df <- data.frame(x = rnorm(10), y = rnorm(10))
p1 <- qplot(x = x, y = y, data = df, geom = c("point", "line"), main =
"Test Plot")
print(p1)

p2 <- p1 + theme_poster()

set_poster_defaults()
print(p2)
unset_poster_defaults()

> Thanks, Bryan

baptiste auguie

unread,
Jul 18, 2011, 5:22:44 PM7/18/11
to Hadley Wickham, Brian Diggs, ggp...@googlegroups.com
Thanks Hadley.

On Tue, Jul 19, 2011 at 1:42 AM, Hadley Wickham <had...@rice.edu> wrote:
>> - choice of mapping geom_text size to fontsize as opposed to cex?
>
> cex makes many things much more difficult because you can no longer
> figure out (e.g.) how wide the axes viewport needs to be, unless you
> know the complete sequence of gTrees/viewports in which it will be
> embedded.

I see; though I would have thought the sizes could be calculated as
rendering time with grobWidth/grobHeight.

>
>> - using modifyList() to specify the changes to themes?
>
> Yes, that's a good idea.

Anyone has a good idea how to overcome the problem that Brian pointed
out? -- namely, base_size and base_family need to be re-specified in
each call to theme_text() because their default values are not
inherited from the theme.

Best,

baptiste

Kohske Takahashi

unread,
Jul 19, 2011, 10:41:09 AM7/19/11
to baptiste auguie, Hadley Wickham, Brian Diggs, ggp...@googlegroups.com
Hi,

> Anyone has a good idea how to overcome the problem that Brian pointed
> out? -- namely, base_size and base_family need to be re-specified in
> each call to theme_text() because their default values are not
> inherited from the theme.
>

During development of a new guides (see another post), Hadley and I wrote this.
You can find it at:
https://github.com/kohske/ggplot2/commit/002e510d0ad80fd3ee4701678b06a30b0aae949f#R/theme.r

--
Kohske Takahashi <takahash...@gmail.com>

Research Center for Advanced Science and Technology,
The University of  Tokyo, Japan.
http://www.fennel.rcast.u-tokyo.ac.jp/profilee_ktakahashi.html

baptiste auguie

unread,
Jul 19, 2011, 4:47:14 PM7/19/11
to Kohske Takahashi, ggplot2, Hadley Wickham, Brian Diggs
Thanks, Kohske!

I have had issues that prevented me to install the dev version of
ggplot2, but I'll try to get this to work and also test your legend
package. From the commit log you refer to, I gather that themes will
be used to set individual style parameters, is my interpretation
correct? In any case, we can probably use modifyList() for the wiki
theme proposals for now.

Best,

baptiste

Kohske Takahashi

unread,
Jul 20, 2011, 4:38:16 PM7/20/11
to baptiste auguie, ggplot2, Hadley Wickham, Brian Diggs
Hi

I'm not yet following all discussion so I'm not sure if I understand
correctly what you said.
here is an example:

> tg <- theme_grey(base_size = 18)
> tt <- tg$legend.title
> tt
theme_text(family = base_family, face = "bold", size = base_size *
0.8, hjust = 0)
> tt2 <- update_element(tt, face = "italic")
> tt2
theme_text(family = "", face = "italic", size = 14.4, hjust = 0)

thus, in this example, tt2 has size = 14.4 ( = 18 * 0.8), keeping all
parameters other than face.
but please not that this function (update_element) and, more
generally, the theme system may be changed in the future version.


--
Kohske Takahashi <takahash...@gmail.com>

Research Center for Advanced Science and Technology,
The University of  Tokyo, Japan.
http://www.fennel.rcast.u-tokyo.ac.jp/profilee_ktakahashi.html

On Wed, Jul 20, 2011 at 5:47 AM, baptiste auguie

baptiste auguie

unread,
Jul 21, 2011, 12:27:47 AM7/21/11
to Kohske Takahashi, ggplot2, Hadley Wickham, Brian Diggs
Hi,

On Thu, Jul 21, 2011 at 8:38 AM, Kohske Takahashi
<takahash...@gmail.com> wrote:
> Hi
>
> I'm not yet following all discussion so I'm not sure  if I understand
> correctly what you said.
> here is an example:
>
>> tg <- theme_grey(base_size = 18)
>> tt <- tg$legend.title
>> tt
> theme_text(family = base_family, face = "bold", size = base_size *
>    0.8, hjust = 0)
>> tt2 <- update_element(tt, face = "italic")
>> tt2
> theme_text(family = "", face = "italic", size = 14.4, hjust = 0)
>
> thus, in this example, tt2 has size = 14.4 ( = 18 * 0.8), keeping all
> parameters other than face.
> but please not that this function (update_element) and, more
> generally, the theme system may be changed in the future version.

What I initially suggested in this thread was incorporating the
functionality of update_element() into the themes themselves,

theme_grey(base_size = 18, legend.title = theme_text(face = "italic"))

where theme_text() would use the set base_size. Alternatively, a more
verbose incantation could be used,

theme_grey(base_size = 18, legend.title = update_element(legend.title,
face = "italic"))


Best,

baptiste

Hadley Wickham

unread,
Aug 15, 2011, 7:51:44 AM8/15/11
to baptiste auguie, Kohske Takahashi, ggplot2, Brian Diggs
> What I initially suggested in this thread was incorporating the
> functionality of update_element() into the themes themselves,
>
> theme_grey(base_size = 18, legend.title = theme_text(face = "italic"))
>
> where theme_text() would use the set base_size. Alternatively, a more
> verbose incantation could be used,
>
> theme_grey(base_size = 18, legend.title = update_element(legend.title,
> face = "italic"))

I think themes really need a complete re-think, because the mechanism
of extension that I thought would be most used (creating new theme_XXX
elements) is very really used, and it would be much more useful to
have some sort of inheritance so that axis.text.x would inherit
properties from axis, text and x theme components.

Reply all
Reply to author
Forward
0 new messages