@ -0,0 +1,11 @@ | |||
^.*\.Rproj$ | |||
^\.Rproj\.user$ | |||
^\.travis\.yml$ | |||
^README\.*Rmd$ | |||
^README\.*html$ | |||
^NOTES\.*Rmd$ | |||
^NOTES\.*html$ | |||
^notes\.txt$ | |||
^CONDUCT\.md$ | |||
^README_files$ | |||
^notes$ |
@ -0,0 +1,8 @@ | |||
.Rproj.user | |||
.Rhistory | |||
.RData | |||
.Rproj | |||
src/*.o | |||
src/*.so | |||
src/*.dll | |||
notes.txt |
@ -0,0 +1,24 @@ | |||
language: r | |||
warnings_are_errors: true | |||
sudo: required | |||
r: | |||
- oldrel | |||
- release | |||
- devel | |||
apt_packages: | |||
- libv8-dev | |||
- xclip | |||
env: | |||
global: | |||
- CRAN: http://cran.rstudio.com | |||
notifications: | |||
email: | |||
- bob@rud.is | |||
irc: | |||
channels: | |||
- "104.236.112.222#builds" | |||
nick: travisci |
@ -0,0 +1,25 @@ | |||
# Contributor Code of Conduct | |||
As contributors and maintainers of this project, we pledge to respect all people who | |||
contribute through reporting issues, posting feature requests, updating documentation, | |||
submitting pull requests or patches, and other activities. | |||
We are committed to making participation in this project a harassment-free experience for | |||
everyone, regardless of level of experience, gender, gender identity and expression, | |||
sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion. | |||
Examples of unacceptable behavior by participants include the use of sexual language or | |||
imagery, derogatory comments or personal attacks, trolling, public or private harassment, | |||
insults, or other unprofessional conduct. | |||
Project maintainers have the right and responsibility to remove, edit, or reject comments, | |||
commits, code, wiki edits, issues, and other contributions that are not aligned to this | |||
Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed | |||
from the project team. | |||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by | |||
opening an issue or contacting one or more of the project maintainers. | |||
This Code of Conduct is adapted from the Contributor Covenant | |||
(http:contributor-covenant.org), version 1.0.0, available at | |||
http://contributor-covenant.org/version/1/0/0/ |
@ -0,0 +1,23 @@ | |||
Package: hrbrthemes | |||
Type: Package | |||
Title: Additional Themes and Theme Components for 'ggplot2' | |||
Version: 0.1.0 | |||
Date: 2017-02-11 | |||
Author: Bob Rudis (bob@rud.is) | |||
Maintainer: Bob Rudis <bob@rud.is> | |||
Description: A compilation of extra themes and theme components for 'ggplot2' | |||
with an emphasis on typography. | |||
URL: http://github.com/hrbrmstr/hrbrthemes | |||
BugReports: https://github.com/hrbrmstr/hrbrthemes/issues | |||
License: AGPL | |||
Suggests: | |||
testthat, | |||
dplyr | |||
Depends: | |||
R (>= 3.2.0) | |||
Imports: | |||
ggplot2 (>= 2.1.0), | |||
grid, | |||
scales, | |||
extrafont | |||
RoxygenNote: 6.0.0 |
@ -0,0 +1,12 @@ | |||
# Generated by roxygen2: do not edit by hand | |||
export(font_an) | |||
export(scale_x_comma) | |||
export(scale_y_comma) | |||
export(scale_y_percent) | |||
export(theme_ipsum) | |||
export(update_geom_font_defaults) | |||
import(extrafont) | |||
import(ggplot2) | |||
import(grid) | |||
import(scales) |
@ -0,0 +1,2 @@ | |||
0.1.0 | |||
* Initial release |
@ -0,0 +1,22 @@ | |||
#' Additional Themes and Theme Components for 'ggplot2' | |||
#' | |||
#' A compilation of extra themes and theme components for 'ggplot2' with an | |||
#' emphasis on typography. | |||
#' | |||
#' The core theme: `theme_ipsum` ("ipsum" is Latin for "precise") uses Arial Narrow | |||
#' which should be installed on practically any modern system, so it's "free"-ish. | |||
#' This font is condensed, has solid default kerning pairs and geometric numbers. | |||
#' That's what I consider the "font trifecta" must-have for charts. An additional | |||
#' quality for fonts for charts is that they have a diversity of weights. Arial | |||
#' Narrow (the one on most systems, anyway) does not have said diversity but this | |||
#' quality is not (IMO) a "must have". | |||
#' | |||
#' @md | |||
#' @name hrbrthemes | |||
#' @docType package | |||
#' @author Bob Rudis (bob@@rud.is) | |||
#' @import ggplot2 | |||
#' @import grid | |||
#' @import scales | |||
#' @import extrafont | |||
NULL |
@ -0,0 +1,99 @@ | |||
# Stolen from ggplot2 | |||
is.waive <- function (x) { inherits(x, "waiver") } | |||
is.sec_axis <- function (x) { inherits(x, "AxisSecondary") } | |||
is.formula <- function (x) { inherits(x, "formula") } | |||
#' X & Y scales with opinionated pre-sets for percent & comma label formats | |||
#' | |||
#' The `_comma` ones set comma format for axis text and `expand=c(0,0)` (you need to set limits). | |||
#' | |||
#' The `_percent` ones set precent format for axis text and `expand=c(0,0)` (you need to set limits). | |||
#' | |||
#' @md | |||
#' @inheritParams ggplot2::scale_x_continuous | |||
scale_x_percent <- function (name = waiver(), breaks = waiver(), minor_breaks = waiver(), | |||
labels = scales::percent, limits = NULL, expand = c(0,0), oob = censor, | |||
na.value = NA_real_, trans = "identity", position = "bottom", | |||
sec.axis = waiver()) { | |||
sc <- ggplot2::continuous_scale(c("x", "xmin", "xmax", "xend", "xintercept", | |||
"xmin_final", "xmax_final", "xlower", "xmiddle", "xupper"), | |||
"position_c", identity, name = name, breaks = breaks, | |||
minor_breaks = minor_breaks, labels = labels, limits = limits, | |||
expand = expand, oob = oob, na.value = na.value, trans = trans, | |||
guide = "none", position = position, super = ScaleContinuousPosition) | |||
if (!is.waive(sec.axis)) { | |||
if (is.formula(sec.axis)) | |||
sec.axis <- sec_axis(sec.axis) | |||
if (!is.sec_axis(sec.axis)) | |||
stop("Secondary axes must be specified using 'sec_axis()'") | |||
sc$secondary.axis <- sec.axis | |||
} | |||
sc | |||
} | |||
#' @rdname scale_x_percent | |||
#' @export | |||
scale_y_percent <- function (name = waiver(), breaks = waiver(), minor_breaks = waiver(), | |||
labels = scales::percent, limits = NULL, expand = c(0,0), oob = censor, | |||
na.value = NA_real_, trans = "identity", position = "left", | |||
sec.axis = waiver()) { | |||
sc <- ggplot2::continuous_scale(c("y", "ymin", "ymax", "yend", "yintercept", | |||
"ymin_final", "ymax_final", "lower", "middle", "upper"), | |||
"position_c", identity, name = name, breaks = breaks, | |||
minor_breaks = minor_breaks, labels = labels, limits = limits, | |||
expand = expand, oob = oob, na.value = na.value, trans = trans, | |||
guide = "none", position = position, super = ScaleContinuousPosition) | |||
if (!is.waive(sec.axis)) { | |||
if (is.formula(sec.axis)) | |||
sec.axis <- ggplot2::sec_axis(sec.axis) | |||
if (!is.sec_axis(sec.axis)) | |||
stop("Secondary axes must be specified using 'sec_axis()'") | |||
sc$secondary.axis <- sec.axis | |||
} | |||
sc | |||
} | |||
#' @rdname scale_x_percent | |||
#' @export | |||
scale_x_comma <- function (name = waiver(), breaks = waiver(), minor_breaks = waiver(), | |||
labels = scales::comma, limits = NULL, expand = c(0,0), oob = censor, | |||
na.value = NA_real_, trans = "identity", position = "bottom", | |||
sec.axis = waiver()) { | |||
sc <- ggplot2::continuous_scale(c("x", "xmin", "xmax", "xend", "xintercept", | |||
"xmin_final", "xmax_final", "xlower", "xmiddle", "xupper"), | |||
"position_c", identity, name = name, breaks = breaks, | |||
minor_breaks = minor_breaks, labels = labels, limits = limits, | |||
expand = expand, oob = oob, na.value = na.value, trans = trans, | |||
guide = "none", position = position, super = ScaleContinuousPosition) | |||
if (!is.waive(sec.axis)) { | |||
if (is.formula(sec.axis)) | |||
sec.axis <- ggplot2::sec_axis(sec.axis) | |||
if (!is.sec_axis(sec.axis)) | |||
stop("Secondary axes must be specified using 'sec_axis()'") | |||
sc$secondary.axis <- sec.axis | |||
} | |||
sc | |||
} | |||
#' @rdname scale_x_percent | |||
#' @export | |||
scale_y_comma <- function (name = waiver(), breaks = waiver(), minor_breaks = waiver(), | |||
labels = scales::comma, limits = NULL, expand = c(0,0), oob = censor, | |||
na.value = NA_real_, trans = "identity", position = "left", | |||
sec.axis = waiver()) { | |||
sc <- ggplot2::continuous_scale(c("y", "ymin", "ymax", "yend", "yintercept", | |||
"ymin_final", "ymax_final", "lower", "middle", "upper"), | |||
"position_c", identity, name = name, breaks = breaks, | |||
minor_breaks = minor_breaks, labels = labels, limits = limits, | |||
expand = expand, oob = oob, na.value = na.value, trans = trans, | |||
guide = "none", position = position, super = ScaleContinuousPosition) | |||
if (!is.waive(sec.axis)) { | |||
if (is.formula(sec.axis)) | |||
sec.axis <- ggplot2::sec_axis(sec.axis) | |||
if (!is.sec_axis(sec.axis)) | |||
stop("Secondary axes must be specified using 'sec_axis()'") | |||
sc$secondary.axis <- sec.axis | |||
} | |||
sc | |||
} |
@ -0,0 +1,179 @@ | |||
#' A precise & pristine [ggplot2] theme with opinionated defaults and an emphasis on typoghraphy | |||
#' | |||
#' @md | |||
#' @section Why Arial Narrow?: | |||
#' First and foremost, Arial Narrow is generally installed by default or readily | |||
#' available on any modern system, so it's "free"-ish; plus, it is a condensed font | |||
#' with solid default kerning pairs and geometric numbers. | |||
#' | |||
#' @section Building upon `theme_ipsum`: | |||
#' The function is setup in such a way that you can customize your own one by just | |||
#' wrapping the call and changing the parameters. See source for examples. | |||
#' | |||
#' @section Gotchas: | |||
#' There are distinctions between font names and various devices. Names that work | |||
#' for display graphics devices and bitmap ones such as `png` may not work well | |||
#' for PostScript or PDF ones. You may need two versions of a font-based | |||
#' theme function for them to work in a particular situation. This situation | |||
#' usually only arises when using a newer font with many weights but somewhat | |||
#' irregular internal font name patterns. | |||
#' | |||
#' @md | |||
#' @param base_family,base_size base font family and size | |||
#' @param plot_title_family,plot_title_face,plot_title_size,plot_title_margin plot tilte family, face, size and margi | |||
#' @param subtitle_family,subtitle_face,subtitle_size plot subtitle family, face and size | |||
#' @param subtitle_margin plot subtitle margin bottom (single numeric value) | |||
#' @param strip_text_family,strip_text_face,strip_text_size facet label font family, face and size | |||
#' @param caption_family,caption_face,caption_size,caption_margin plot caption family, face, size and margin | |||
#' @param axis_title_family,axis_title_face,axis_title_size axis title font family, face and size | |||
#' @param axis_title_just axis title font justificationk one of `[blmcrt]` | |||
#' @param plot_margin plot margin (specify with [ggplot2::margin]) | |||
#' @param grid panel grid (`TRUE`, `FALSE`, or a combination of `X`, `x`, `Y`, `y`) | |||
#' @param axis add x or y axes? `TRUE`, `FALSE`, "`xy`" | |||
#' @param ticks ticks if `TRUE` add ticks | |||
#' @export | |||
#' @examples \dontrun{ | |||
#' library(ggplot2) | |||
#' library(dplyr) | |||
#' | |||
#' # seminal scatterplot | |||
#' ggplot(mtcars, aes(mpg, wt)) + | |||
#' geom_point() + | |||
#' labs(x="Fuel effiiency (mpg)", y="Weight (tons)", | |||
#' title="Seminal ggplot2 scatterplot example", | |||
#' subtitle="A plot that is only useful for demonstration purposes", | |||
#' caption="Brought to you by the letter 'g'") + | |||
#' theme_ipsum() | |||
#' | |||
#' # seminal bar chart | |||
#' library(dplyr) | |||
#' | |||
#' update_geom_font_defaults() | |||
#' | |||
#' count(mpg, class) %>% | |||
#' ggplot(aes(class, n)) + | |||
#' geom_col() + | |||
#' geom_text(aes(label=n), nudge_y=3) + | |||
#' labs(x="Fuel effiiency (mpg)", y="Weight (tons)", | |||
#' title="Seminal ggplot2 bar chart example", | |||
#' subtitle="A plot that is only useful for demonstration purposes", | |||
#' caption="Brought to you by the letter 'g'") + | |||
#' theme_ipsum(grid="Y") + | |||
#' theme(axis.text.y=element_blank()) | |||
#' } | |||
theme_ipsum <- function(base_family="Arial Narrow", base_size = 11, | |||
plot_title_family="Arial Narrow", plot_title_size = 18, | |||
plot_title_face="bold", plot_title_margin = 10, | |||
subtitle_family="Arial Narrow", subtitle_size = 12, | |||
subtitle_face = "plain", subtitle_margin = 15, | |||
strip_text_family = "Arial Narrow", strip_text_size = 12, | |||
strip_text_face = "plain", | |||
caption_family = "Arial Narrow", caption_size = 9, | |||
caption_face = "italic", caption_margin = 10, | |||
axis_title_family = subtitle_family, axis_title_size = 9, | |||
axis_title_face = "plain", axis_title_just = "rt", | |||
plot_margin = margin(30, 30, 30, 30), | |||
grid = TRUE, axis = FALSE, ticks = FALSE) { | |||
ret <- ggplot2::theme_minimal(base_family=base_family, base_size=base_size) | |||
ret <- ret + theme(legend.background=element_blank()) | |||
ret <- ret + theme(legend.key=element_blank()) | |||
if (inherits(grid, "character") | grid == TRUE) { | |||
ret <- ret + theme(panel.grid=element_line(color="#2b2b2bdd", size=0.10)) | |||
ret <- ret + theme(panel.grid.major=element_line(color="#2b2b2b99", size=0.10)) | |||
ret <- ret + theme(panel.grid.minor=element_line(color="#2b2b2b99", size=0.05)) | |||
if (inherits(grid, "character")) { | |||
if (regexpr("X", grid)[1] < 0) ret <- ret + theme(panel.grid.major.x=element_blank()) | |||
if (regexpr("Y", grid)[1] < 0) ret <- ret + theme(panel.grid.major.y=element_blank()) | |||
if (regexpr("x", grid)[1] < 0) ret <- ret + theme(panel.grid.minor.x=element_blank()) | |||
if (regexpr("y", grid)[1] < 0) ret <- ret + theme(panel.grid.minor.y=element_blank()) | |||
} | |||
} else { | |||
ret <- ret + theme(panel.grid=element_blank()) | |||
} | |||
if (inherits(axis, "character") | axis == TRUE) { | |||
ret <- ret + theme(axis.line=element_line(color="#2b2b2b", size=0.15)) | |||
if (inherits(axis, "character")) { | |||
axis <- tolower(axis) | |||
if (regexpr("x", axis)[1] < 0) { | |||
ret <- ret + theme(axis.line.x=element_blank()) | |||
} else { | |||
ret <- ret + theme(axis.line.x=element_line(color="#2b2b2b", size=0.15)) | |||
} | |||
if (regexpr("y", axis)[1] < 0) { | |||
ret <- ret + theme(axis.line.y=element_blank()) | |||
} else { | |||
ret <- ret + theme(axis.line.y=element_line(color="#2b2b2b", size=0.15)) | |||
} | |||
} else { | |||
ret <- ret + theme(axis.line.x=element_line(color="#2b2b2b", size=0.15)) | |||
ret <- ret + theme(axis.line.y=element_line(color="#2b2b2b", size=0.15)) | |||
} | |||
} else { | |||
ret <- ret + theme(axis.line=element_blank()) | |||
} | |||
if (!ticks) { | |||
ret <- ret + theme(axis.ticks = element_blank()) | |||
ret <- ret + theme(axis.ticks.x = element_blank()) | |||
ret <- ret + theme(axis.ticks.y = element_blank()) | |||
} else { | |||
ret <- ret + theme(axis.ticks = element_line(size=0.15)) | |||
ret <- ret + theme(axis.ticks.x = element_line(size=0.15)) | |||
ret <- ret + theme(axis.ticks.y = element_line(size=0.15)) | |||
ret <- ret + theme(axis.ticks.length = grid::unit(5, "pt")) | |||
} | |||
xj <- switch(tolower(substr(axis_title_just, 1, 1)), b=0, l=0, m=0.5, c=0.5, r=1, t=1) | |||
yj <- switch(tolower(substr(axis_title_just, 2, 2)), b=0, l=0, m=0.5, c=0.5, r=1, t=1) | |||
ret <- ret + theme(axis.text.x=element_text(margin=margin(t=0))) | |||
ret <- ret + theme(axis.text.y=element_text(margin=margin(r=0))) | |||
ret <- ret + theme(axis.title=element_text(size=axis_title_size, family=axis_title_family)) | |||
ret <- ret + theme(axis.title.x=element_text(hjust=xj, size=axis_title_size, | |||
family=axis_title_family, face=axis_title_face)) | |||
ret <- ret + theme(axis.title.y=element_text(hjust=yj, size=axis_title_size, | |||
family=axis_title_family, face=axis_title_face)) | |||
ret <- ret + theme(strip.text=element_text(hjust=0, size=strip_text_size, | |||
face=strip_text_face, family=strip_text_family)) | |||
ret <- ret + theme(panel.spacing.x=grid::unit(2, "lines")) | |||
ret <- ret + theme(panel.spacing.y=grid::unit(2, "lines")) | |||
ret <- ret + theme(plot.title=element_text(hjust=0, size=plot_title_size, | |||
margin=margin(b=plot_title_margin), | |||
family=plot_title_family, face=plot_title_face)) | |||
ret <- ret + theme(plot.subtitle=element_text(hjust=0, size=subtitle_size, | |||
margin=margin(b=subtitle_margin), | |||
family=subtitle_family, face=subtitle_face)) | |||
ret <- ret + theme(plot.caption=element_text(hjust=1, size=caption_size, | |||
margin=margin(t=caption_margin), | |||
family=caption_family, face=caption_face)) | |||
ret <- ret + theme(plot.margin=plot_margin) | |||
ret | |||
} | |||
#' Update matching font defaults for text geoms | |||
#' | |||
#' Updates [ggplot2::geom_label] and [ggplot2::geom_text] font defaults | |||
#' | |||
#' @param family,face,size font family name, face and size | |||
#' @export | |||
update_geom_font_defaults <- function(family="Arial Narrow", face="plain", size=3.5) { | |||
update_geom_defaults("text", list(family=family, face=face, size=size)) | |||
update_geom_defaults("label", list(family=family, face=face, size=size)) | |||
} | |||
#' @rdname ArialNarrow | |||
#' @md | |||
#' @title Arial Narrow font name R variable aliases | |||
#' @description `font_an` == "`Arial Narrow`" | |||
#' @format length 1 character vector | |||
#' @export | |||
font_an <- "Arial Narrow" |
@ -0,0 +1,101 @@ | |||
--- | |||
output: rmarkdown::github_document | |||
--- | |||
`hrbrthemes` : Additional Themes and Theme Components for 'ggplot2' | |||
This is a very focused package that provides typography-centric themes and theme components for ggplot2. It's a an extract/riff of [`hrbrmisc`](http://github.com/hrbrmstr/hrbrmisc) created by request. | |||
The core theme: `theme_ipsum` ("ipsum" is Latin for "precise") uses Arial Narrow which should be installed on practically any modern system, so it's "free"-ish. This font is condensed, has solid default kerning pairs and geometric numbers. That's what I consider the "font trifecta" must-have for charts. An additional quality for fonts for charts is that they have a diversity of weights. Arial Narrow (the one on most systems, anyway) does not have said diversity but this quality is not (IMO) a "must have". | |||
The following functions are implemented/objects are exported: | |||
- `theme_ipsum` : Arial Narrow-based theme | |||
- `update_geom_font_defaults`: Update matching font defaults for text geoms (the default is — unsurprisingly — Arial Narrow) | |||
- `scale_x_comma` / `scale_y_comma` : Comma format for axis text and `expand=c(0,0)` (you need to set limits) | |||
- `scale_x_percent` / `scale_y_percent` : Percent format for axis text and `expand=c(0,0)` (you need to set limits) | |||
- `font_an`: a short global alias for "`Arial Narrow`" | |||
### TODO | |||
- Creation of supplemental extra font packages with instructions for installation | |||
- Additional base themes to match ^^ | |||
- At least one new custom color & fill scale | |||
- Whatever ends up in a feature request in an issue that makes sense ;-) | |||
### Installation | |||
```{r eval=FALSE} | |||
devtools::install_github("hrbrmstr/hrbrthemes") | |||
``` | |||
```{r message=FALSE, warning=FALSE, error=FALSE} | |||
options(width=120) | |||
``` | |||
### Usage | |||
```{r message=FALSE, warning=FALSE, error=FALSE} | |||
library(hrbrthemes) | |||
library(tidyverse) | |||
# current verison | |||
packageVersion("hrbrthemes") | |||
``` | |||
### Base theme (Arial Narrow) | |||
```{r fig.retina=2} | |||
ggplot(mtcars, aes(mpg, wt)) + | |||
geom_point() + | |||
labs(x="Fuel effiiency (mpg)", y="Weight (tons)", | |||
title="Seminal ggplot2 scatterplot example", | |||
subtitle="A plot that is only useful for demonstration purposes", | |||
caption="Brought to you by the letter 'g'") + | |||
theme_ipsum() | |||
``` | |||
### Scales | |||
```{r fig.retina=2} | |||
count(mpg, class) %>% | |||
mutate(pct=n/sum(n)) %>% | |||
ggplot(aes(class, pct)) + | |||
geom_col() + | |||
scale_y_percent() + | |||
labs(x="Fuel effiiency (mpg)", y="Weight (tons)", | |||
title="Seminal ggplot2 column chart example with percents", | |||
subtitle="A plot that is only useful for demonstration purposes", | |||
caption="Brought to you by the letter 'g'") + | |||
theme_ipsum(grid="Y") | |||
``` | |||
```{r fig.retina=2} | |||
count(mpg, class) %>% | |||
mutate(n=n*2000) %>% | |||
arrange(n) %>% | |||
mutate(class=factor(class, levels=class)) %>% | |||
ggplot(aes(class, n)) + | |||
geom_col() + | |||
scale_y_comma() + | |||
coord_flip() + | |||
labs(x="Fuel effiiency (mpg)", y="Weight (tons)", | |||
title="Seminal ggplot2 column chart example with commas", | |||
subtitle="A plot that is only useful for demonstration purposes", | |||
caption="Brought to you by the letter 'g'") + | |||
theme_ipsum(grid="X") | |||
``` | |||
### Test Results | |||
```{r message=FALSE, warning=FALSE, error=FALSE} | |||
library(hrbrthemes) | |||
library(testthat) | |||
date() | |||
test_dir("tests/") | |||
``` | |||
### Code of Conduct | |||
Please note that this project is released with a [Contributor Code of Conduct](CONDUCT.md). By participating in this project you agree to abide by its terms. |
@ -0,0 +1,116 @@ | |||
`hrbrthemes` : Additional Themes and Theme Components for 'ggplot2' | |||
This is a very focused package that provides typography-centric themes and theme components for ggplot2. It's a an extract/riff of [`hrbrmisc`](http://github.com/hrbrmstr/hrbrmisc) created by request. | |||
The core theme: `theme_ipsum` ("ipsum" is Latin for "precise") uses Arial Narrow which should be installed on practically any modern system, so it's "free"-ish. This font is condensed, has solid default kerning pairs and geometric numbers. That's what I consider the "font trifecta" must-have for charts. An additional quality for fonts for charts is that they have a diversity of weights. Arial Narrow (the one on most systems, anyway) does not have said diversity but this quality is not (IMO) a "must have". | |||
The following functions are implemented/objects are exported: | |||
- `theme_ipsum` : Arial Narrow-based theme | |||
- `update_geom_font_defaults`: Update matching font defaults for text geoms (the default is — unsurprisingly — Arial Narrow) | |||
- `scale_x_comma` / `scale_y_comma` : Comma format for axis text and `expand=c(0,0)` (you need to set limits) | |||
- `scale_x_percent` / `scale_y_percent` : Percent format for axis text and `expand=c(0,0)` (you need to set limits) | |||
- `font_an`: a short global alias for "`Arial Narrow`" | |||
### TODO | |||
- Creation of supplemental extra font packages with instructions for installation | |||
- Additional base themes to match ^^ | |||
- At least one new custom color & fill scale | |||
- Whatever ends up in a feature request in an issue that makes sense ;-) | |||
### Installation | |||
``` r | |||
devtools::install_github("hrbrmstr/hrbrthemes") | |||
``` | |||
``` r | |||
options(width=120) | |||
``` | |||
### Usage | |||
``` r | |||
library(hrbrthemes) | |||
library(tidyverse) | |||
# current verison | |||
packageVersion("hrbrthemes") | |||
``` | |||
## [1] '0.1.0' | |||
### Base theme (Arial Narrow) | |||
``` r | |||
ggplot(mtcars, aes(mpg, wt)) + | |||
geom_point() + | |||
labs(x="Fuel effiiency (mpg)", y="Weight (tons)", | |||
title="Seminal ggplot2 scatterplot example", | |||
subtitle="A plot that is only useful for demonstration purposes", | |||
caption="Brought to you by the letter 'g'") + | |||
theme_ipsum() | |||
``` | |||
<img src="README_files/figure-markdown_github/unnamed-chunk-4-1.png" width="672" /> | |||
### Scales | |||
``` r | |||
count(mpg, class) %>% | |||
mutate(pct=n/sum(n)) %>% | |||
ggplot(aes(class, pct)) + | |||
geom_col() + | |||
scale_y_percent() + | |||
labs(x="Fuel effiiency (mpg)", y="Weight (tons)", | |||
title="Seminal ggplot2 column chart example with percents", | |||
subtitle="A plot that is only useful for demonstration purposes", | |||
caption="Brought to you by the letter 'g'") + | |||
theme_ipsum(grid="Y") | |||
``` | |||
<img src="README_files/figure-markdown_github/unnamed-chunk-5-1.png" width="672" /> | |||
``` r | |||
count(mpg, class) %>% | |||
mutate(n=n*2000) %>% | |||
arrange(n) %>% | |||
mutate(class=factor(class, levels=class)) %>% | |||
ggplot(aes(class, n)) + | |||
geom_col() + | |||
scale_y_comma() + | |||
coord_flip() + | |||
labs(x="Fuel effiiency (mpg)", y="Weight (tons)", | |||
title="Seminal ggplot2 column chart example with commas", | |||
subtitle="A plot that is only useful for demonstration purposes", | |||
caption="Brought to you by the letter 'g'") + | |||
theme_ipsum(grid="X") | |||
``` | |||
<img src="README_files/figure-markdown_github/unnamed-chunk-6-1.png" width="672" /> | |||
### Test Results | |||
``` r | |||
library(hrbrthemes) | |||
library(testthat) | |||
date() | |||
``` | |||
## [1] "Sat Feb 11 12:01:25 2017" | |||
``` r | |||
test_dir("tests/") | |||
``` | |||
## testthat results ======================================================================================================== | |||
## OK: 0 SKIPPED: 0 FAILED: 0 | |||
## | |||
## DONE =================================================================================================================== | |||
### Code of Conduct | |||
Please note that this project is released with a [Contributor Code of Conduct](CONDUCT.md). By participating in this project you agree to abide by its terms. |
@ -0,0 +1,21 @@ | |||
Version: 1.0 | |||
RestoreWorkspace: Default | |||
SaveWorkspace: Default | |||
AlwaysSaveHistory: Default | |||
EnableCodeIndexing: Yes | |||
UseSpacesForTab: Yes | |||
NumSpacesForTab: 2 | |||
Encoding: UTF-8 | |||
RnwWeave: Sweave | |||
LaTeX: pdfLaTeX | |||
StripTrailingWhitespace: Yes | |||
BuildType: Package | |||
PackageUseDevtools: Yes | |||
PackageInstallArgs: --no-multiarch --with-keep.source | |||
PackageBuildArgs: --resave-data | |||
PackageRoxygenize: rd,collate,namespace |
@ -0,0 +1,14 @@ | |||
% Generated by roxygen2: do not edit by hand | |||
% Please edit documentation in R/theme-ipsum.r | |||
\docType{data} | |||
\name{font_an} | |||
\alias{font_an} | |||
\title{Arial Narrow font name R variable aliases} | |||
\format{length 1 character vector} | |||
\usage{ | |||
font_an | |||
} | |||
\description{ | |||
\code{font_an} == "\code{Arial Narrow}" | |||
} | |||
\keyword{datasets} |
@ -0,0 +1,23 @@ | |||
% Generated by roxygen2: do not edit by hand | |||
% Please edit documentation in R/hrbrthemes-package.R | |||
\docType{package} | |||
\name{hrbrthemes} | |||
\alias{hrbrthemes} | |||
\alias{hrbrthemes-package} | |||
\title{Additional Themes and Theme Components for 'ggplot2'} | |||
\description{ | |||
A compilation of extra themes and theme components for 'ggplot2' with an | |||
emphasis on typography. | |||
} | |||
\details{ | |||
The core theme: \code{theme_ipsum} ("ipsum" is Latin for "precise") uses Arial Narrow | |||
which should be installed on practically any modern system, so it's "free"-ish. | |||
This font is condensed, has solid default kerning pairs and geometric numbers. | |||
That's what I consider the "font trifecta" must-have for charts. An additional | |||
quality for fonts for charts is that they have a diversity of weights. Arial | |||
Narrow (the one on most systems, anyway) does not have said diversity but this | |||
quality is not (IMO) a "must have". | |||
} | |||
\author{ | |||
Bob Rudis (bob@rud.is) | |||
} |
@ -0,0 +1,96 @@ | |||
% Generated by roxygen2: do not edit by hand | |||
% Please edit documentation in R/scales.r | |||
\name{scale_x_percent} | |||
\alias{scale_x_percent} | |||
\alias{scale_y_percent} | |||
\alias{scale_x_comma} | |||
\alias{scale_y_comma} | |||
\title{X & Y scales with opinionated pre-sets for percent & comma label formats} | |||
\usage{ | |||
scale_x_percent(name = waiver(), breaks = waiver(), | |||
minor_breaks = waiver(), labels = scales::percent, limits = NULL, | |||
expand = c(0, 0), oob = censor, na.value = NA_real_, | |||
trans = "identity", position = "bottom", sec.axis = waiver()) | |||
scale_y_percent(name = waiver(), breaks = waiver(), | |||
minor_breaks = waiver(), labels = scales::percent, limits = NULL, | |||
expand = c(0, 0), oob = censor, na.value = NA_real_, | |||
trans = "identity", position = "left", sec.axis = waiver()) | |||
scale_x_comma(name = waiver(), breaks = waiver(), minor_breaks = waiver(), | |||
labels = scales::comma, limits = NULL, expand = c(0, 0), oob = censor, | |||
na.value = NA_real_, trans = "identity", position = "bottom", | |||
sec.axis = waiver()) | |||
scale_y_comma(name = waiver(), breaks = waiver(), minor_breaks = waiver(), | |||
labels = scales::comma, limits = NULL, expand = c(0, 0), oob = censor, | |||
na.value = NA_real_, trans = "identity", position = "left", | |||
sec.axis = waiver()) | |||
} | |||
\arguments{ | |||
\item{name}{The name of the scale. Used as axis or legend title. If | |||
\code{NULL}, the default, the name of the scale is taken from the first | |||
mapping used for that aesthetic.} | |||
\item{breaks}{One of: \itemize{ | |||
\item \code{NULL} for no breaks | |||
\item \code{waiver()} for the default breaks computed by the | |||
transformation object | |||
\item A numeric vector of positions | |||
\item A function that takes the limits as input and returns breaks | |||
as output | |||
}} | |||
\item{minor_breaks}{One of: \itemize{ | |||
\item \code{NULL} for no minor breaks | |||
\item \code{waiver()} for the default breaks (one minor break between | |||
each major break) | |||
\item A numeric vector of positions | |||
\item A function that given the limits returns a vector of minor breaks. | |||
}} | |||
\item{labels}{One of: \itemize{ | |||
\item \code{NULL} for no labels | |||
\item \code{waiver()} for the default labels computed by the | |||
transformation object | |||
\item A character vector giving labels (must be same length as \code{breaks}) | |||
\item A function that takes the breaks as input and returns labels | |||
as output | |||
}} | |||
\item{limits}{A numeric vector of length two providing limits of the scale. | |||
Use \code{NA} to refer to the existing minimum or maximum.} | |||
\item{expand}{A numeric vector of length two giving multiplicative and | |||
additive expansion constants. These constants ensure that the data is | |||
placed some distance away from the axes. The defaults are | |||
\code{c(0.05, 0)} for continuous variables, and \code{c(0, 0.6)} for | |||
discrete variables.} | |||
\item{oob}{Function that handles limits outside of the scale limits | |||
(out of bounds). The default replaces out of bounds values with NA.} | |||
\item{na.value}{Missing values will be replaced with this value.} | |||
\item{trans}{Either the name of a transformation object, or the | |||
object itself. Built-in transformations include "asn", "atanh", | |||
"boxcox", "exp", "identity", "log", "log10", "log1p", "log2", | |||
"logit", "probability", "probit", "reciprocal", "reverse" and "sqrt". | |||
A transformation object bundles together a transform, it's inverse, | |||
and methods for generating breaks and labels. Transformation objects | |||
are defined in the scales package, and are called \code{name_trans}, e.g. | |||
\code{\link[scales]{boxcox_trans}}. You can create your own | |||
transformation with \code{\link[scales]{trans_new}}.} | |||
\item{position}{The position of the axis. "left" or "right" for vertical | |||
scales, "top" or "bottom" for horizontal scales} | |||
\item{sec.axis}{specifify a secondary axis} | |||
} | |||
\description{ | |||
The \code{_comma} ones set comma format for axis text and \code{expand=c(0,0)} (you need to set limits). | |||
} | |||
\details{ | |||
The \code{_percent} ones set precent format for axis text and \code{expand=c(0,0)} (you need to set limits). | |||
} |
@ -0,0 +1,101 @@ | |||
% Generated by roxygen2: do not edit by hand | |||
% Please edit documentation in R/theme-ipsum.r | |||
\name{theme_ipsum} | |||
\alias{theme_ipsum} | |||
\title{A precise & pristine \link{ggplot2} theme with opinionated defaults and an emphasis on typoghraphy} | |||
\usage{ | |||
theme_ipsum(base_family = "Arial Narrow", base_size = 11, | |||
plot_title_family = "Arial Narrow", plot_title_size = 18, | |||
plot_title_face = "bold", plot_title_margin = 10, | |||
subtitle_family = "Arial Narrow", subtitle_size = 12, | |||
subtitle_face = "plain", subtitle_margin = 15, | |||
strip_text_family = "Arial Narrow", strip_text_size = 12, | |||
strip_text_face = "plain", caption_family = "Arial Narrow", | |||
caption_size = 9, caption_face = "italic", caption_margin = 10, | |||
axis_title_family = subtitle_family, axis_title_size = 9, | |||
axis_title_face = "plain", axis_title_just = "rt", | |||
plot_margin = margin(30, 30, 30, 30), grid = TRUE, axis = FALSE, | |||
ticks = FALSE) | |||
} | |||
\arguments{ | |||
\item{base_family, base_size}{base font family and size} | |||
\item{plot_title_family, plot_title_face, plot_title_size, plot_title_margin}{plot tilte family, face, size and margi} | |||
\item{subtitle_family, subtitle_face, subtitle_size}{plot subtitle family, face and size} | |||
\item{subtitle_margin}{plot subtitle margin bottom (single numeric value)} | |||
\item{strip_text_family, strip_text_face, strip_text_size}{facet label font family, face and size} | |||
\item{caption_family, caption_face, caption_size, caption_margin}{plot caption family, face, size and margin} | |||
\item{axis_title_family, axis_title_face, axis_title_size}{axis title font family, face and size} | |||
\item{axis_title_just}{axis title font justificationk one of \code{[blmcrt]}} | |||
\item{plot_margin}{plot margin (specify with \link[ggplot2:margin]{ggplot2::margin})} | |||
\item{grid}{panel grid (\code{TRUE}, \code{FALSE}, or a combination of \code{X}, \code{x}, \code{Y}, \code{y})} | |||
\item{axis}{add x or y axes? \code{TRUE}, \code{FALSE}, "\code{xy}"} | |||
\item{ticks}{ticks if \code{TRUE} add ticks} | |||
} | |||
\description{ | |||
A precise & pristine \link{ggplot2} theme with opinionated defaults and an emphasis on typoghraphy | |||
} | |||
\section{Why Arial Narrow?}{ | |||
First and foremost, Arial Narrow is generally installed by default or readily | |||
available on any modern system, so it's "free"-ish; plus, it is a condensed font | |||
with solid default kerning pairs and geometric numbers. | |||
} | |||
\section{Building upon \code{theme_ipsum}}{ | |||
The function is setup in such a way that you can customize your own one by just | |||
wrapping the call and changing the parameters. See source for examples. | |||
} | |||
\section{Gotchas}{ | |||
There are distinctions between font names and various devices. Names that work | |||
for display graphics devices and bitmap ones such as \code{png} may not work well | |||
for PostScript or PDF ones. You may need two versions of a font-based | |||
theme function for them to work in a particular situation. This situation | |||
usually only arises when using a newer font with many weights but somewhat | |||
irregular internal font name patterns. | |||
} | |||
\examples{ | |||
\dontrun{ | |||
library(ggplot2) | |||
library(dplyr) | |||
# seminal scatterplot | |||
ggplot(mtcars, aes(mpg, wt)) + | |||
geom_point() + | |||
labs(x="Fuel effiiency (mpg)", y="Weight (tons)", | |||
title="Seminal ggplot2 scatterplot example", | |||
subtitle="A plot that is only useful for demonstration purposes", | |||
caption="Brought to you by the letter 'g'") + | |||
theme_ipsum() | |||
# seminal bar chart | |||
library(dplyr) | |||
update_geom_font_defaults() | |||
count(mpg, class) \%>\% | |||
ggplot(aes(class, n)) + | |||
geom_col() + | |||
geom_text(aes(label=n), nudge_y=3) + | |||
labs(x="Fuel effiiency (mpg)", y="Weight (tons)", | |||
title="Seminal ggplot2 bar chart example", | |||
subtitle="A plot that is only useful for demonstration purposes", | |||
caption="Brought to you by the letter 'g'") + | |||
theme_ipsum(grid="Y") + | |||
theme(axis.text.y=element_blank()) | |||
} | |||
} |
@ -0,0 +1,15 @@ | |||
% Generated by roxygen2: do not edit by hand | |||
% Please edit documentation in R/theme-ipsum.r | |||
\name{update_geom_font_defaults} | |||
\alias{update_geom_font_defaults} | |||
\title{Update matching font defaults for text geoms} | |||
\usage{ | |||
update_geom_font_defaults(family = "Arial Narrow", face = "plain", | |||
size = 3.5) | |||
} | |||
\arguments{ | |||
\item{family, face, size}{font family name, face and size} | |||
} | |||
\description{ | |||
Updates [ggplot2::geom_label] and [ggplot2::geom_text] font defaults | |||
} |
@ -0,0 +1,2 @@ | |||
library(testthat) | |||
test_check("hrbrthemes") |
@ -0,0 +1,6 @@ | |||
context("basic functionality") | |||
test_that("we can do something", { | |||
#expect_that(some_function(), is_a("data.frame")) | |||
}) |