Source file ⇒ lec12.Rmd
The theming system in ggplot2 enables a user to control non-data elements of a ggplot object. It is composed of the following:
theme elements, which refer to individual attributes of a graphic that are independent of the data, such as font size, axis ticks, appearance of grid lines or background color of a legend;
theme element functions, which enables you to modify the settings of certain theme elements;
theme functions, which define the settings of a collection of theme elements for the purpose of creating a specific style of graphics production;
the theme() function, used to locally modify one or more theme elements in a specific ggplot object.
Consider the following simple scatterplot using the mpg data:
mpg %>% ggplot( aes(x = cty, y = hwy, color = factor(cyl))) +
geom_jitter() +
labs(
x = "City mileage/gallon",
y = "Highway mileage/gallon",
color = "Cylinders"
)
Suppose we want to make the following modifications to this plot:
The first of these depends on the data itself, so we can use one of the scale_colour_*()
functions for that purpose —see ggplot2 help.
The others influence the rendering of the graphic but are independent of the data being plotted. These are called theme elements, i.e., aspects of a ggplot object that are capable of modifying its appearance but are neither directly related to data nor aesthetics associated with data.
theme_grey()
The output of this call lists the properties of a ggplot object that can be accessed by users along with their default values, expressed as a list of lists. The theme() function allows you to locally modify properties of theme elements in a ggplot object.
One way of implementing the desired changes listed above is as follows:
p <- mpg %>% ggplot( aes(x = cty, y = hwy, colour = factor(cyl))) +
geom_jitter() +
labs(
x = "City mileage/gallon",
y = "Highway mileage/gallon",
colour = "Cylinders"
) +
scale_colour_brewer(type = "seq", palette = "Oranges")
# Use theme() to modify theme elements
p + labs(title = "Highway vs. city mileage per gallon") +
theme(
axis.text = element_text(size = 14),
plot.title = element_text(size=12),
legend.key = element_rect(fill = "navy"),
legend.background = element_rect(fill = "white"),
legend.position = c(0.14, 0.80),
panel.grid.major = element_line(colour = "grey40"),
panel.grid.minor = element_blank(),
panel.background = element_rect(fill = "navy")
)
The element_xx()
functions modify theme elements with attributes (e.g., color, text size). Some theme elements are defined in terms of a unit of measurement, while others, such as legend.position, control the positioning of a theme element. These will be illustrated in greater detail in the examples to follow.
In the above call, element_text()
modifies the size property of the axis.text
theme element, element_rect()
changes the fill color of the legend.key
, legend.background
and panel.background
theme elements, element_line()
alters the color of the major grid lines in both directions and element_blank()
removes the minor grid lines from the display in both directions. Finally, the form of the legend.position()
call moves the center of the legend grob to a position in coordinates relative to the size of the overall graphics device (not the graphics panel that delimits the graph itself). In this case, the default theme function is theme_grey()
, so theme()
locally changes the above settings in theme_grey()
to the values specified in the call.
Copy the previous chunk and make modifications to produce the following plot:
p <- mpg %>% ggplot( aes(x = cty, y = hwy, colour = factor(cyl))) +
geom_jitter() +
labs(
x = "City mileage/gallon",
y = "Highway mileage/gallon",
colour = "Cylinders"
) +
scale_colour_brewer(type = "seq", palette = "Oranges")
# Use theme() to modify theme elements
p + labs(title = "Highway vs. city mileage per gallon") +
theme(
axis.text = element_text(size = 20),
plot.title = element_text(size = 20,color = "red"),
legend.key = element_rect(fill = "black"),
legend.background = element_rect(fill = "white"),
legend.position = "right",
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_rect(fill = "grey40")
)
The default theme for ggplot2 graphics is theme_grey()
, but you can override it with another (complete) theme function. A second theme function built into the system is theme_bw()
, which can be plugged in as a replacement for theme_grey()
as follows:
p + labs(title = "Highway vs. city mileage per gallon") +
theme_bw() +
theme(axis.text = element_text(size = 14),
legend.key = element_rect(fill = "navy"),
legend.background = element_rect(fill = "white"),
legend.position = c(0.14, 0.80),
panel.grid.major = element_line(colour = "grey40"),
panel.grid.minor = element_blank()
)
Adding theme_bw()
to the ggplot() call means that theme_bw
becomes the default theme for the created ggplot object. The call theme_bw()
produces a theme object which can be modified with theme()
.
Most theme elements have several properties that can be modified through a corresponding element function.
element_text()
element_line()
element_rect()
element_blank()
element_text()
Purpose: To control the drawing of labels and headings.
The table below lists the arguments of element_text() and their corresponding default values.
Argument | Description | Default |
---|---|---|
family | font family | “” |
face | font face | plain |
colour | font color | black |
size | font size | 10 |
hjust | horizontal justification | 0.5 |
vjust | vertical justification | 0.5 |
angle | text angle | 0 |
lineheight | line height | 1.1 |
element_line()
Purpose: To draw lines and segments such as graphics region boundaries, axis tick marks and grid lines.
Arument | Description | Default |
---|---|---|
colour | line color | black |
size | line thinkness | 0.5 |
linetype | type of line | 1 |
element_rect()
Purpose: To draw rectangles. It is mostly used for background elements and legend keys.
Arguement | Description | Default |
---|---|---|
fill | fill color | none |
colour | border color | black |
size | thinkness of border line | 0.5 |
linetype | type of border line | 1 |
echo_blank()
Purpose: To draw nothing.
Arguments: none.
The element_blank() function can be applied to any theme element controlled by a theme element function.
Here are some theme elements for you to modify using the element functions above
here is a complete list: ggplot-themes
set.seed(123)
df <- diamonds[sample(1:nrow(diamonds), size = 1000),]
df %>% ggplot(aes(carat, price)) +
geom_point() +
theme(axis.ticks = element_line(size = 10))
set.seed(123)
df <- diamonds[sample(1:nrow(diamonds), size = 1000),]
df %>% ggplot(aes(carat, price)) +
geom_point() +
theme(axis.ticks = element_blank(), axis.text =element_text(size=20), panel.background= element_rect(fill = "blue"), panel.grid =element_line(linetype=2) )
The default theme function theme_grey()
contains 38 individual theme elements. The first three of these are line
, rect
and text
, whose default properties are defined through their respective theme element functions element_line()
, element_rect()
and element_text()
.
The first three elements in ggplot-themes are text
, line
and rect
, which, not coincidentally, are the same as the names of the basic theme element functions. Other theme elements inherit the values of these theme elements. For example, the theme elements axis.text
, legend.text
, strip.text
and axis.title
all inherit from text, while axis.text.x
and axis.text.y
further inherit from axis.text
. This means the values of the components of the theme element text are passed on to axis.text as well as other elements that inherit from text or its children. You can override the default values of one or more theme elements by calling theme()
and modifying the desired properties of theme elements therein.
Here is a useful figure: inheritance:
Here is an example:
set.seed(123)
df <- diamonds[sample(1:nrow(diamonds), size = 1000),]
df %>% ggplot(aes(carat, price)) +
geom_point() +
theme(axis.ticks = element_blank(), text =element_text(size=30), panel.background= element_rect(fill= "blue"), panel.grid =element_line(linetype=2) )
A theme function is an R function in ggplot2 that sets or parameterizes a collection of theme elements. Although the default themes in ggplot2 produce attractive graphics, they may not necessarily correspond with user requirements. If you find yourself modifying the same theme elements repeatedly with theme()
or need to adapt a set of theme elements to conform to the requirements of a journal or other publication, then you should consider writing your own theme function.
The purpose of a theme function is to either specify default settings for each theme element or modify the settings of an existing theme function to produce a new theme. For example, the foundational theme_grey
function specifies default settings of each theme element, whereas theme_bw
is a modification of theme_grey
.
There are nice theme functions made by other users:
library(ggthemes)
##
## Attaching package: 'ggthemes'
## The following object is masked from 'package:mosaic':
##
## theme_map
mpg %>% ggplot( aes(x = cty, y = hwy, color = factor(cyl))) +
geom_jitter() +
labs(
x = "City mileage/gallon",
y = "Highway mileage/gallon",
color = "Cylinders"
) + theme_igray()
If you want all your figures to use a certain theme here is how to do it.
Say my old default theme is theme_grey()
I have written my own theme called theme_pink
that I would like to use in all of my plots.
theme_pink <- theme(panel.background = element_blank(),
legend.key = element_blank(),
legend.background = element_blank(),
strip.background = element_blank(),
plot.background = element_rect(fill = "red", color = "black", size = 3),
panel.grid = element_blank(),
axis.line = element_line(color = "black"),
axis.ticks = element_line(color = "black"),
strip.text = element_text(size = 16, color = "red"),
axis.title.y = element_text(color = "red", hjust = 0, face = "italic"),
axis.title.x = element_text(color = "red", hjust = 0, face = "italic"),
axis.text = element_text(color = "black"),
legend.position = "none")
mpg %>% ggplot( aes(x = cty, y = hwy, color = factor(cyl))) +
geom_jitter() +
labs(
x = "City mileage/gallon",
y = "Highway mileage/gallon",
color = "Cylinders"
) + theme_pink
You can make this your default theme using theme_update()
. The value of the this function is your old theme which you can save: old <- theme_update()
old=theme_update(panel.background = element_blank(),
legend.key = element_blank(),
legend.background = element_blank(),
strip.background = element_blank(),
plot.background = element_rect(fill = "red", color = "black", size = 3),
panel.grid = element_blank(),
axis.line = element_line(color = "black"),
axis.ticks = element_line(color = "black"),
strip.text = element_text(size = 16, color = "red"),
axis.title.y = element_text(color = "red", hjust = 0, face = "italic"),
axis.title.x = element_text(color = "red", hjust = 0, face = "italic"),
axis.text = element_text(color = "black"),
legend.position = "none")
set.seed(123)
df <- diamonds[sample(1:nrow(diamonds), size = 1000),]
df %>% ggplot(aes(carat, price)) +
geom_point() +
theme(axis.ticks = element_line(size = 10))
You can restore your old theme
theme_set(old)
set.seed(123)
df <- diamonds[sample(1:nrow(diamonds), size = 1000),]
df %>% ggplot(aes(carat, price)) +
geom_point() +
theme(axis.ticks = element_line(size = 10))
Here is a list of colors
Colors can specified as a hexadecimal RGB triplet, such as “#0066CC”. The first two digits are the level of red, the next two green, and the last two blue. The value for each ranges from 00 to FF in hexadecimal (base-16) notation, which is equivalent to 0 and 255 in base-10. For example, in the table below, “#FFFFFF” is white and “#990000” is a deep red.
hexadecimal:
Try some different colors in the code below (try hexadecimal and non hexadecimal code)
set.seed(955)
# Make some noisily increasing data
dat <- data.frame(xvar = 1:20 + rnorm(20,sd=3),
yvar = 1:20 + rnorm(20,sd=3))
ggplot(dat, aes(x=xvar, y=yvar)) +
geom_point(shape=1) + # Use hollow circles
geom_smooth(method=lm, fill="azure1") # Add linear regression line
set.seed(955)
# Make some noisily increasing data
dat <- data.frame(xvar = 1:20 + rnorm(20,sd=3),
yvar = 1:20 + rnorm(20,sd=3))
ggplot(dat, aes(x=xvar, y=yvar)) +
geom_point(shape=1) + # Use hollow circles
geom_smooth(method=lm, fill="#9AF308") # Add linear regression line