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

Subtitles for ggplot2 #1582

Merged
merged 14 commits into from Mar 15, 2016

Conversation

Projects
None yet
5 participants
@hrbrmstr
Contributor

hrbrmstr commented Mar 13, 2016

  • new subtitle parameter for labs and ggtitle
  • documented the subtitle parameter in ggtitle since it's an explicit parameter
  • new caption parameter for labs function
  • new plot.subtitle theme element
  • new plot.caption theme element (default alignment is right-justified)
  • updated default alignment for plot.title and plot.subtitle (now left-justified by default)
  • updated roxygen documentation with subtitle and caption examples
  • added test for title, subtitle & caption settings
  • cleaned up = spacing in a few other files since they came up when I was trying to fix my own :-)
  • updated NEWS.md (including suggested fixes to NEWS.md)

Sample code to validate non-breakage (i.e. test with various plot elements):

library(ggplot2)
library(gridExtra)

st <- "Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all people are created equal."
st <- paste0(strwrap(st, 70), sep="", collapse="\n")

p <- ggplot(mtcars, aes(wt, mpg))
p <- p + geom_point(aes(color=factor(cyl)))

# Changing the font solely to validate functionality. Times. Ugh.
p <- p + theme(text=element_text(family="Times"))
p <- p + theme(plot.title=element_text(face="bold"))
p <- p + theme(plot.subtitle=element_text(margin=margin(b=15)))
p <- p + theme(plot.caption=element_text(margin=margin(t=15),
                                        face="italic", size=8))
grid.arrange(

  p + ggtitle("Just ggtitle"),

  p + labs(title="Just labs with title"),

  p + ggtitle("Now ggtitle with title subtitle", subtitle=st),

  # More tests --------------------------------------------------------------

  p + labs(title="Now labs with title subtitle", subtitle=st) +
    theme(legend.position="top"),

  p + labs(title="Two separate labs calls for each title") +
    labs(subtitle=st) +
    theme(legend.position="bottom"),

  p + facet_wrap(~cyl) +
    labs(title="Works with facets too",
         subtitle=st,
         caption="Brought you by the letters 'gg'"),

  # below -------------------------------------------------------------------

  p + labs(title="Now labs with title subtitle & below",
           subtitle=st,
           source="Brought you by the letters 'gg'"),

  p + labs(title="Two separate labs calls for each title & below") +
    labs(subtitle=st) +
    labs(caption="Brought you by the letters 'gg'") +
    theme(legend.position="bottom"),

  p + facet_wrap(~cyl) +
    labs(title="Works with facets too & below",
         subtitle=st,
         caption="Brought you by the letters 'gg'"),

  ncol=3

)

image

Show outdated Hide outdated R/labels.r
labs(title = label)
ggtitle <- function(label, subtitle) {
if (!missing(subtitle)) {
labs(title = label, subtitle = subtitle)

This comment has been minimized.

@hadley

hadley Mar 13, 2016

Member

Simpler to give subtitle a default value of NULL?

@hadley

hadley Mar 13, 2016

Member

Simpler to give subtitle a default value of NULL?

@hadley

This comment has been minimized.

Show comment
Hide comment
@hadley

hadley Mar 13, 2016

Member

This is appealingly simple!

Member

hadley commented Mar 13, 2016

This is appealingly simple!

@jankatins

This comment has been minimized.

Show comment
Hide comment
@jankatins

jankatins Mar 13, 2016

Contributor

[Follow up from twitter: https://twitter.com/hrbrmstr/status/709102677351911424]

@hrbrmstr The cowplot code is this: https://github.com/wilkelab/cowplot/blob/master/R/add_sub.R -> very similar to what you have here.

What I'm not sure is what to name it: adding it as an additional option to ggtitle does not feel right.

From the documentation in cowplot:

#' Add annotation underneath a plot
#' This function can add an arbitrary label or mathematical expression underneath
#' the plot, similar to the \code{sub} parameter in base R.

I can do a PR against your repo but my R is not as good as yours so I'm not sure what is faster for you... :-(

Contributor

jankatins commented Mar 13, 2016

[Follow up from twitter: https://twitter.com/hrbrmstr/status/709102677351911424]

@hrbrmstr The cowplot code is this: https://github.com/wilkelab/cowplot/blob/master/R/add_sub.R -> very similar to what you have here.

What I'm not sure is what to name it: adding it as an additional option to ggtitle does not feel right.

From the documentation in cowplot:

#' Add annotation underneath a plot
#' This function can add an arbitrary label or mathematical expression underneath
#' the plot, similar to the \code{sub} parameter in base R.

I can do a PR against your repo but my R is not as good as yours so I'm not sure what is faster for you... :-(

@@ -254,6 +258,11 @@ print.theme <- function(x, ...) utils::str(x)
#' p + theme(plot.title = element_text(size = rel(2)))
#' p + theme(plot.title = element_text(size = rel(2), colour = "blue"))
#'
#' # Add a subtitle and adjust bottom margin
#' p + labs(title = "Vehicle Weight-Gas Mileage Relationship",
#' subtitle = "You need to wrap long subtitleson manually") +

This comment has been minimized.

@jankatins

jankatins Mar 13, 2016

Contributor

s/subtitleson/subtitles/?

@jankatins

jankatins Mar 13, 2016

Contributor

s/subtitleson/subtitles/?

@jankatins

This comment has been minimized.

Show comment
Hide comment
@jankatins

jankatins Mar 14, 2016

Contributor

I added a PR for whole plot annotations: https://github.com/hrbrmstr/ggplot2/pull/1

# Can add plot annotations underneath the whole plot (for sources, notes or
# copyright), similar to the \code{sub} parameter in base R, with the
# following
p + labs(sub = "(based on data from ...)")

I used sub because that's what it called in base R. Not sure if there is a better name ("notice"? "annotation"?)... It's currently only accessible via labs(sub="..."), not ggtitle (doesn't feel right). Maybe a notice(...)?

[Update: Ok, just found out that sub is a bad idea because it's a substring of subtitle and therefore adding a subtitle and no sub will also show the subtitle in the sub... -> I will change it to annotation]

Contributor

jankatins commented Mar 14, 2016

I added a PR for whole plot annotations: https://github.com/hrbrmstr/ggplot2/pull/1

# Can add plot annotations underneath the whole plot (for sources, notes or
# copyright), similar to the \code{sub} parameter in base R, with the
# following
p + labs(sub = "(based on data from ...)")

I used sub because that's what it called in base R. Not sure if there is a better name ("notice"? "annotation"?)... It's currently only accessible via labs(sub="..."), not ggtitle (doesn't feel right). Maybe a notice(...)?

[Update: Ok, just found out that sub is a bad idea because it's a substring of subtitle and therefore adding a subtitle and no sub will also show the subtitle in the sub... -> I will change it to annotation]

Add whole plot annotations
Annotations are added below the plot similar to similar to the `sub` parameter
in base R.

p + labs(annotation="(based in data from ...)")
Show outdated Hide outdated R/theme.r
#' (\code{element_text}; inherits from \code{title}) \cr
#' (\code{element_text}; inherits from \code{title})
#' left-aligned by default\cr
#' plot.subtitle \tab plot title (text appearance)

This comment has been minimized.

@jankatins

jankatins Mar 14, 2016

Contributor

s/plot title/plot subtitle/ (this is in my PR)

@jankatins

jankatins Mar 14, 2016

Contributor

s/plot title/plot subtitle/ (this is in my PR)

@jankatins

This comment has been minimized.

Show comment
Hide comment
@jankatins

jankatins Mar 14, 2016

Contributor
library(ggplot2)
library(ggplot2)
library(gridExtra)

st <- "Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal."
st <- paste0(strwrap(st, 70), sep="", collapse="\n")

p <- ggplot(mtcars, aes(wt, mpg))
p <- p + geom_point()

# Changing the font solely to validate functionality. Times. Ugh.
p <- p + theme(text=element_text(family="Times"))
p <- p + theme(plot.title=element_text(face="bold"))
p <- p + theme(plot.subtitle=element_text(margin=margin(b=15)))
p <- p + labs(title="Now labs with title subtitle", subtitle=st)

grid.arrange(
  p,
  p + labs(annotation="(based on mtcars dataset available in R)"),
  p + labs(annotation="(based on mtcars dataset available in R)") + 
    theme(plot.annotation=element_text(face="bold", hjust = 1)),
  ncol=3
)

rplot01

Contributor

jankatins commented Mar 14, 2016

library(ggplot2)
library(ggplot2)
library(gridExtra)

st <- "Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal."
st <- paste0(strwrap(st, 70), sep="", collapse="\n")

p <- ggplot(mtcars, aes(wt, mpg))
p <- p + geom_point()

# Changing the font solely to validate functionality. Times. Ugh.
p <- p + theme(text=element_text(family="Times"))
p <- p + theme(plot.title=element_text(face="bold"))
p <- p + theme(plot.subtitle=element_text(margin=margin(b=15)))
p <- p + labs(title="Now labs with title subtitle", subtitle=st)

grid.arrange(
  p,
  p + labs(annotation="(based on mtcars dataset available in R)"),
  p + labs(annotation="(based on mtcars dataset available in R)") + 
    theme(plot.annotation=element_text(face="bold", hjust = 1)),
  ncol=3
)

rplot01

@hrbrmstr

This comment has been minimized.

Show comment
Hide comment
@hrbrmstr

hrbrmstr Mar 14, 2016

Contributor

Incorporated the PR (tweaked the docs a bit). Fixed the Travis error. Rejiggered the visual validation (see new image above).

Contributor

hrbrmstr commented Mar 14, 2016

Incorporated the PR (tweaked the docs a bit). Fixed the Travis error. Rejiggered the visual validation (see new image above).

Show outdated Hide outdated R/theme.r
#' plot.subtitle \tab plot subtitle (text appearance)
#' (\code{element_text}; inherits from \code{title})
#' left-aligned by default\cr
#' plot.sub \tab annotations below the plot (text appearance)

This comment has been minimized.

@jankatins

jankatins Mar 14, 2016

Contributor

s/plot.sub/plot.annotation/...

PR in your repo...

@jankatins

jankatins Mar 14, 2016

Contributor

s/plot.sub/plot.annotation/...

PR in your repo...

Show outdated Hide outdated NEWS.md
* `ggtitle` and `labs` now take a `subtitle` parameter which makes it
possible to add a subtitle below the main plot title.
* `labs` now takes an `annotation` parameter that will set the label for

This comment has been minimized.

@hadley

hadley Mar 14, 2016

Member

"annotation" sounds way too generic for me. What about "source"?

@hadley

hadley Mar 14, 2016

Member

"annotation" sounds way too generic for me. What about "source"?

This comment has been minimized.

@hadley

hadley Mar 14, 2016

Member

Also my style is to add () to function names

@hadley

hadley Mar 14, 2016

Member

Also my style is to add () to function names

Show outdated Hide outdated NEWS.md
annotation text below the plot panels
* the main plot title and subtitle are left-justified (`hjust = 0`) by
default, now

This comment has been minimized.

@hadley

hadley Mar 14, 2016

Member

You can drop ", now".

Can you please make it a proper sentence with leading capital and trailing period?

@hadley

hadley Mar 14, 2016

Member

You can drop ", now".

Can you please make it a proper sentence with leading capital and trailing period?

Show outdated Hide outdated R/labels.r
#' @rdname labs
#' @export
ggtitle <- function(label) {
labs(title = label)
ggtitle <- function(label, subtitle=NULL) {

This comment has been minimized.

@hadley

hadley Mar 14, 2016

Member

Missing spaces around =

@hadley

hadley Mar 14, 2016

Member

Missing spaces around =

This comment has been minimized.

@hrbrmstr

hrbrmstr Mar 14, 2016

Contributor

will fix (remind me never to poke CRAN about their barriers to entry ;-)

On Mon, Mar 14, 2016 at 6:32 PM, Hadley Wickham notifications@github.com
wrote:

In R/labels.r
#1582 (comment):

#' @rdname labs
#' @export
-ggtitle <- function(label) {

  • labs(title = label)
    +ggtitle <- function(label, subtitle=NULL) {

Missing spaces around =


Reply to this email directly or view it on GitHub
https://github.com/hadley/ggplot2/pull/1582/files#r56087824.

@hrbrmstr

hrbrmstr Mar 14, 2016

Contributor

will fix (remind me never to poke CRAN about their barriers to entry ;-)

On Mon, Mar 14, 2016 at 6:32 PM, Hadley Wickham notifications@github.com
wrote:

In R/labels.r
#1582 (comment):

#' @rdname labs
#' @export
-ggtitle <- function(label) {

  • labs(title = label)
    +ggtitle <- function(label, subtitle=NULL) {

Missing spaces around =


Reply to this email directly or view it on GitHub
https://github.com/hadley/ggplot2/pull/1582/files#r56087824.

@hadley

This comment has been minimized.

Show comment
Hide comment
@hadley

hadley Mar 14, 2016

Member

Looking good, just a few minor niggles left.

Member

hadley commented Mar 14, 2016

Looking good, just a few minor niggles left.

Show outdated Hide outdated R/theme-elements.r
@@ -278,6 +278,8 @@ el_def <- function(class = NULL, inherit = NULL, description = NULL) {
plot.background = el_def("element_rect", "rect"),
plot.title = el_def("element_text", "title"),
plot.subtitle = el_def("element_text", "title"),
plot.annotation = el_def("element_text", "title"),

This comment has been minimized.

@hadley

hadley Mar 14, 2016

Member

Should this default to right alignment?

@hadley

hadley Mar 14, 2016

Member

Should this default to right alignment?

This comment has been minimized.

@hrbrmstr

hrbrmstr Mar 14, 2016

Contributor

that's a good q. if we set it to that by default and let folks play with
devtools version of ggplot2, we'll def get community feedback. I'll mod
that too.

On Mon, Mar 14, 2016 at 6:33 PM, Hadley Wickham notifications@github.com
wrote:

In R/theme-elements.r
#1582 (comment):

@@ -278,6 +278,8 @@ el_def <- function(class = NULL, inherit = NULL, description = NULL) {

plot.background = el_def("element_rect", "rect"),
plot.title = el_def("element_text", "title"),

  • plot.subtitle = el_def("element_text", "title"),
  • plot.annotation = el_def("element_text", "title"),

Should this default to right alignment?


Reply to this email directly or view it on GitHub
https://github.com/hadley/ggplot2/pull/1582/files#r56087991.

@hrbrmstr

hrbrmstr Mar 14, 2016

Contributor

that's a good q. if we set it to that by default and let folks play with
devtools version of ggplot2, we'll def get community feedback. I'll mod
that too.

On Mon, Mar 14, 2016 at 6:33 PM, Hadley Wickham notifications@github.com
wrote:

In R/theme-elements.r
#1582 (comment):

@@ -278,6 +278,8 @@ el_def <- function(class = NULL, inherit = NULL, description = NULL) {

plot.background = el_def("element_rect", "rect"),
plot.title = el_def("element_text", "title"),

  • plot.subtitle = el_def("element_text", "title"),
  • plot.annotation = el_def("element_text", "title"),

Should this default to right alignment?


Reply to this email directly or view it on GitHub
https://github.com/hadley/ggplot2/pull/1582/files#r56087991.

@jankatins

This comment has been minimized.

Show comment
Hide comment
@jankatins

jankatins Mar 15, 2016

Contributor

re "annotation" vs "source": They will probably be used for at least three use cases: source statements, copyright statements, and notices for explanations regarding the plots (depending on your style, the last could also go to the subtitle). That's why I settled on "annotations" which in my (non native) understanding encompasses all three use cases.

Contributor

jankatins commented Mar 15, 2016

re "annotation" vs "source": They will probably be used for at least three use cases: source statements, copyright statements, and notices for explanations regarding the plots (depending on your style, the last could also go to the subtitle). That's why I settled on "annotations" which in my (non native) understanding encompasses all three use cases.

@hadley

This comment has been minimized.

Show comment
Hide comment
@hadley

hadley Mar 15, 2016

Member

Annotation is already used elsewhere in ggplot2 for a different purpose, so that name is definitely out. How about footer?

Member

hadley commented Mar 15, 2016

Annotation is already used elsewhere in ggplot2 for a different purpose, so that name is definitely out. How about footer?

@hrbrmstr

This comment has been minimized.

Show comment
Hide comment
@hrbrmstr

hrbrmstr Mar 15, 2016

Contributor

Lynn (Cherny) just suggested "caption" (I'm crowdsourcing this on Twitter
with some vis ppl :-)

On Tue, Mar 15, 2016 at 9:48 AM, Hadley Wickham notifications@github.com
wrote:

Annotation is already used elsewhere in ggplot2 for a different purpose,
so that name is definitely out. How about footer?


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#1582 (comment)

Contributor

hrbrmstr commented Mar 15, 2016

Lynn (Cherny) just suggested "caption" (I'm crowdsourcing this on Twitter
with some vis ppl :-)

On Tue, Mar 15, 2016 at 9:48 AM, Hadley Wickham notifications@github.com
wrote:

Annotation is already used elsewhere in ggplot2 for a different purpose,
so that name is definitely out. How about footer?


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#1582 (comment)

@hadley

This comment has been minimized.

Show comment
Hide comment
@hadley

hadley Mar 15, 2016

Member

Oh, I like "caption"!

Member

hadley commented Mar 15, 2016

Oh, I like "caption"!

@hrbrmstr

This comment has been minimized.

Show comment
Hide comment
@hrbrmstr

hrbrmstr Mar 15, 2016

Contributor

I'll shall make said change when I'm off the train to Boston.

On Tue, Mar 15, 2016 at 10:02 AM, Hadley Wickham notifications@github.com
wrote:

Oh, I like "caption"!


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#1582 (comment)

Contributor

hrbrmstr commented Mar 15, 2016

I'll shall make said change when I'm off the train to Boston.

On Tue, Mar 15, 2016 at 10:02 AM, Hadley Wickham notifications@github.com
wrote:

Oh, I like "caption"!


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:
#1582 (comment)

@jankatins

This comment has been minimized.

Show comment
Hide comment
@jankatins

jankatins Mar 15, 2016

Contributor

Damn, wasn't fast enough: https://github.com/hrbrmstr/ggplot2/pull/3

Contributor

jankatins commented Mar 15, 2016

Damn, wasn't fast enough: https://github.com/hrbrmstr/ggplot2/pull/3

Show outdated Hide outdated NEWS.md
@@ -4,6 +4,19 @@
aesthetics they accept: `xmin_final`, `xmax_final`, `xlower`,
`xmiddle` and `xupper` are now valid `x` aesthetics.
* `ggtitle()` and `labs()` take a `subtitle` parameter which makes it

This comment has been minimized.

@hadley

hadley Mar 15, 2016

Member

One last thing - can you please credit yourself here, i.e. (@hrbmstr)

@hadley

hadley Mar 15, 2016

Member

One last thing - can you please credit yourself here, i.e. (@hrbmstr)

This comment has been minimized.

@hrbrmstr

hrbrmstr Mar 15, 2016

Contributor

done.

@hrbrmstr

hrbrmstr Mar 15, 2016

Contributor

done.

jankatins and others added some commits Mar 15, 2016

Merge pull request #3 from JanSchulz/pr/1582
Change name of whole plot annotations from source to caption
@jankatins

This comment has been minimized.

Show comment
Hide comment
@jankatins

jankatins Mar 15, 2016

Contributor

This actually closes an issue which I opened in 2012: #682 :-)

Contributor

jankatins commented Mar 15, 2016

This actually closes an issue which I opened in 2012: #682 :-)

hadley added a commit that referenced this pull request Mar 15, 2016

@hadley hadley merged commit 59c503b into tidyverse:master Mar 15, 2016

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
@hadley

This comment has been minimized.

Show comment
Hide comment
@hadley

hadley Mar 15, 2016

Member

Thanks!

Member

hadley commented Mar 15, 2016

Thanks!

@patternproject

This comment has been minimized.

Show comment
Hide comment
@patternproject

patternproject Mar 16, 2016

Please suggest: If I need to use this feature, should I pull the latest version from github. I tried as follows:

install_github("hadley/ggplot2/pull/1582")
Downloading GitHub repo hadley/ggplot2@master
from URL https://api.github.com/repos/hadley/ggplot2/zipball/master
Error: Does not appear to be an R package (no DESCRIPTION)

Please suggest: If I need to use this feature, should I pull the latest version from github. I tried as follows:

install_github("hadley/ggplot2/pull/1582")
Downloading GitHub repo hadley/ggplot2@master
from URL https://api.github.com/repos/hadley/ggplot2/zipball/master
Error: Does not appear to be an R package (no DESCRIPTION)

@ptoche

This comment has been minimized.

Show comment
Hide comment
@ptoche

ptoche Oct 5, 2017

Is this feature available? Thanks.

devtools::install_github("tidyverse/ggplot2") 
Error in ggsubtitle("TEST") : 
  could not find function "ggsubtitle"

ptoche commented Oct 5, 2017

Is this feature available? Thanks.

devtools::install_github("tidyverse/ggplot2") 
Error in ggsubtitle("TEST") : 
  could not find function "ggsubtitle"
@hrbrmstr

This comment has been minimized.

Show comment
Hide comment
@hrbrmstr

hrbrmstr Oct 5, 2017

Contributor
Contributor

hrbrmstr commented Oct 5, 2017

@ptoche

This comment has been minimized.

Show comment
Hide comment
@ptoche

ptoche Oct 5, 2017

Thanks!

I liked the ggtitle() syntax for keeping things on single lines.

The following appears to work. I wonder why/if/how/somehow/maybe/like it was not added to the refactored code?

ggsubtitle <- function(x) {
  return(labs(subtitle = x))
}

One and only test:

p <- ggplot(mtcars, aes(mpg, wt, col=factor(cyl))) + geom_point()
p + ggtitle("AA") + ggsubtitle ("BB")

ptoche commented Oct 5, 2017

Thanks!

I liked the ggtitle() syntax for keeping things on single lines.

The following appears to work. I wonder why/if/how/somehow/maybe/like it was not added to the refactored code?

ggsubtitle <- function(x) {
  return(labs(subtitle = x))
}

One and only test:

p <- ggplot(mtcars, aes(mpg, wt, col=factor(cyl))) + geom_point()
p + ggtitle("AA") + ggsubtitle ("BB")

@lock lock bot locked as resolved and limited conversation to collaborators Jun 18, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.