Now that we have covered the important aspects of ggplot, meaning getting the actual plot you wanted, let us now look into secondary elements of the plot.

1 Modifying Axes

1.1 Breaks

If we look at the iris data plot that we made before:

ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width))+
  geom_point(aes(color=Sepal.Width))+
  geom_smooth(method="lm")

The continuous x axis breaks are with 2,4,6 and so on. If we would like to have 1,2,3… We change this using scale_x_continuous() and breaks.

ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width))+
  geom_point(aes(size=Sepal.Width, color=Species))+
  geom_smooth(method="lm") +
  scale_x_continuous(breaks = 1:7)

plot

You can do the same with y-axis.

ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width))+
  geom_point(aes(size=Sepal.Width, color=Species))+
  geom_smooth(method="lm") +
  scale_x_continuous(breaks = 1:7) +
  scale_y_continuous(breaks = seq(0,3,0.5))

plot

1.2 Limits

By using limits, we can also decide on the parts to plot to be shown:

ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width))+
  geom_point(aes(size=Sepal.Width, color=Species)) +
  geom_smooth(method="lm") +
  scale_x_continuous(limits=c(3, 7))

plot

We can do the same with discrete x values like in the case of our gene counts dataset.

gc_long %>% 
  group_by(Time, Replicate) %>% 
  summarise(mean=mean(log10(count +1)),se=se(log10(count +1))) %>%
  ggplot(aes(x=Time, y=mean, fill = Replicate)) + 
  geom_col() + 
  scale_x_discrete(limits=c("t0","t24"))

plot

One can also use xlim() and ylim() functions that function the same as limits with scale_x_continous() or scale_x_discrete()

1.3 Names

You can also customize the axis labels using the name option within scale_x_continous and scale_y_continous.

ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width))+
  geom_point(aes(size=Sepal.Width, color=Species))+
  geom_smooth(method="lm") +
  scale_x_continuous(name = "Length", breaks = 1:7) +
  scale_y_continuous(name = "Width", breaks = seq(0,3,0.5))

plot

with labels in combination with the scales package, one can change or make the unit of the axis look more comprehensible, when needed. Like using percentage option or scientific option.

library(scales)
ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width))+
  geom_point(aes(size=Sepal.Width, color=Species))+
  geom_smooth(method="lm") +
  scale_y_continuous(name = "Width", breaks = seq(0,3,0.5), labels = scientific)

plot

2 Legends

There are many ways to control the legends, below are some of the examples: First by using guides() function.

ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width))+
  geom_point(aes(color=Species,size=Sepal.Width))+
  guides(size="none")

plot

We can also turn off legends by geom.

ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width))+
  geom_point(aes(color=Species,size=Sepal.Width),show.legend=FALSE)

plot

2.1 Editing legends

The legends can be edited by scale_<aesthetic>_<discrete or continous> function that we have been using. Take the below figure for example, we have the Sepal.Width and the Species with the size and color aestheitcs respectively.

ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width))+
  geom_point(aes(size=Sepal.Width, color=Species))+
  geom_smooth(method="lm")

Let’s try to edit the legends here like mentioned before:

ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width))+
  geom_point(aes(size=Sepal.Width, color=Species))+
  geom_smooth(method="lm") +
  scale_size_continuous(name = "Width of Sepal") +
  scale_color_discrete(name = "Organism", labels = c("Iris setosa", "Iris versicolor", "Iris virginica"))

2.2 Moving legends

Legends can be moved around using theme.

ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width))+
  geom_point(aes(color=Species,size=Sepal.Width)) +
  theme(legend.position="top",
        legend.justification="right")

plot

Legend rows can be controlled in a finer manner.

ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width))+
  geom_point(aes(color=Species,size=Sepal.Width))+
  guides(size=guide_legend(nrow=2,byrow=TRUE),
         color=guide_legend(nrow=3,byrow=T))+
  theme(legend.position="top",
        legend.justification="right")

plot

3 Themes

Now that we started into theme(), it is possible to much more editing of the plot with this function. Let us look into some of the parameters that would be very helpful to work with.

3.1 Axis style

You can change the style of the axis texts in the following way:

ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width)) +
  geom_point(aes(color=Species,size=Sepal.Width)) +
  scale_x_continuous(name = "Length", breaks = 1:7) +
  scale_y_continuous(name = "Width", breaks = seq(0,3,0.5)) +
  theme(axis.text.x = element_text(face="bold", color="#993333", size=14, angle=45), 
        axis.text.y = element_text(face="bold", color="#993333", size=14, angle=45))

plot

It is also possible hide the ticks.

ggplot(data=iris,mapping=aes(x=Petal.Length,y=Petal.Width)) +
  geom_point(aes(color=Species,size=Sepal.Width)) +
  scale_x_continuous(name = "Length", breaks = 1:7) +
  scale_y_continuous(name = "Width", breaks = seq(0,3,0.5)) +
  theme(axis.text.x = element_text(face="bold", color="#993333", size=14, angle=45), 
        axis.text.y = element_text(face="bold", color="#993333", size=14, angle=45), 
        axis.ticks = element_blank())

plot

There are many things one can use to style the axis and/or axis labels. Just use ?theme() to look for all the different one can use to stylize the plots.

3.2 Different themes

Let’s consider the plot below and save it as an object P for the sake of simplicity.

P <- gc_long %>% 
  group_by(Time, Replicate) %>% 
  summarise(mean=mean(log10(count +1)),se=se(log10(count +1))) %>%
  ggplot(aes(x= Time, y= mean, fill = Replicate)) + 
  geom_col(position = position_dodge2()) +
  geom_errorbar(aes(ymin=mean-se, ymax=mean+se), position = position_dodge2(.9, padding = .6)) +
  theme(axis.ticks = element_blank())
P

plot

3.2.1 Lighter themes

theme_light(), theme_minimal(), theme_classic() and theme_bw() are a couple of themes that are used very often in publications.

P + theme_bw(base_size = 16)

plot

P + theme_minimal(base_size = 16)

plot

3.2.2 ggthemes package

Let’s look into some of the fancier themes that comes in this package

Q <- ggplot(data = gc_long, mapping = aes(x = Sample_Name, y = log10(count + 1), fill = Time)) + geom_boxplot()
Q  

plot

Using the theme_tufte()

library(ggthemes)
Q + theme_tufte()

plot

Q + theme_economist() + 
  scale_color_economist()

plot

Q + theme_stata() +
  scale_color_stata()

plot

4 Exercise

Task   Try to replicate the plot below if you have enough time.

plot

Tip: 1   geom_line() is a bit tricky when you use it together with groups. It tries to draw lines within the group. In this case, if you would like to draw lines between the groups (like in the above plot, between t0 through t2 to t24), you initate the ggplot with aesthetics for the line and add geom_line(aes(group=1)) this way.

Tip: 2   This figure has theme_light()

5 Session info

sessionInfo()
## R version 4.1.3 (2022-03-10)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 18.04.6 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/openblas/libblas.so.3
## LAPACK: /usr/lib/x86_64-linux-gnu/libopenblasp-r0.2.20.so
## 
## locale:
##  [1] LC_CTYPE=C.UTF-8       LC_NUMERIC=C           LC_TIME=C.UTF-8       
##  [4] LC_COLLATE=C.UTF-8     LC_MONETARY=C.UTF-8    LC_MESSAGES=C.UTF-8   
##  [7] LC_PAPER=C.UTF-8       LC_NAME=C              LC_ADDRESS=C          
## [10] LC_TELEPHONE=C         LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C   
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] ggthemes_4.2.4         scales_1.2.0           ggrepel_0.9.1         
##  [4] wesanderson_0.3.6      forcats_0.5.1          stringr_1.4.0         
##  [7] purrr_0.3.4            readr_2.1.2            tidyr_1.2.0           
## [10] tibble_3.1.6           tidyverse_1.3.1        reshape2_1.4.4        
## [13] ggplot2_3.3.5          formattable_0.2.1      kableExtra_1.3.4      
## [16] dplyr_1.0.8            lubridate_1.8.0        leaflet_2.1.1         
## [19] yaml_2.3.5             fontawesome_0.2.2.9000 captioner_2.2.3       
## [22] bookdown_0.26          knitr_1.39            
## 
## loaded via a namespace (and not attached):
##  [1] httr_1.4.2        sass_0.4.1        jsonlite_1.8.0    viridisLite_0.4.0
##  [5] splines_4.1.3     modelr_0.1.8      bslib_0.3.1       assertthat_0.2.1 
##  [9] highr_0.9         cellranger_1.1.0  pillar_1.7.0      backports_1.4.1  
## [13] lattice_0.20-45   glue_1.6.2        digest_0.6.29     rvest_1.0.2      
## [17] colorspace_2.0-3  htmltools_0.5.2   Matrix_1.4-0      plyr_1.8.7       
## [21] pkgconfig_2.0.3   broom_0.8.0       haven_2.5.0       webshot_0.5.3    
## [25] svglite_2.1.0     tzdb_0.3.0        mgcv_1.8-39       generics_0.1.2   
## [29] farver_2.1.0      ellipsis_0.3.2    withr_2.5.0       cli_3.3.0        
## [33] magrittr_2.0.3    crayon_1.5.1      readxl_1.4.0      evaluate_0.15    
## [37] fs_1.5.2          fansi_1.0.3       nlme_3.1-155      xml2_1.3.3       
## [41] tools_4.1.3       hms_1.1.1         lifecycle_1.0.1   reprex_2.0.1     
## [45] munsell_0.5.0     compiler_4.1.3    jquerylib_0.1.4   systemfonts_1.0.4
## [49] rlang_1.0.2       grid_4.1.3        rstudioapi_0.13   htmlwidgets_1.5.4
## [53] crosstalk_1.2.0   labeling_0.4.2    rmarkdown_2.14    gtable_0.3.0     
## [57] DBI_1.1.2         R6_2.5.1          fastmap_1.1.0     utf8_1.2.2       
## [61] stringi_1.7.6     Rcpp_1.0.8.3      vctrs_0.4.1       dbplyr_2.1.1     
## [65] tidyselect_1.1.2  xfun_0.30