3939 lines
71 KiB
Plaintext
3939 lines
71 KiB
Plaintext
---
|
||
title: "数据可视化"
|
||
subtitle: 《区域水环境污染数据分析实践》<br>Data analysis practice of regional water environment pollution
|
||
author: 苏命、王为东<br>中国科学院大学资源与环境学院<br>中国科学院生态环境研究中心
|
||
date: today
|
||
lang: zh
|
||
format:
|
||
revealjs:
|
||
theme: dark
|
||
slide-number: true
|
||
chalkboard:
|
||
buttons: true
|
||
preview-links: auto
|
||
lang: zh
|
||
toc: true
|
||
toc-depth: 1
|
||
toc-title: 大纲
|
||
logo: ./_extensions/inst/img/ucaslogo.png
|
||
css: ./_extensions/inst/css/revealjs.css
|
||
pointer:
|
||
key: "p"
|
||
color: "#32cd32"
|
||
pointerSize: 18
|
||
revealjs-plugins:
|
||
- pointer
|
||
filters:
|
||
- d2
|
||
knitr:
|
||
opts_chunk:
|
||
dev: "svg"
|
||
retina: 3
|
||
execute:
|
||
freeze: auto
|
||
cache: true
|
||
echo: true
|
||
fig-width: 5
|
||
fig-height: 6
|
||
---
|
||
|
||
```{r}
|
||
#| include: false
|
||
#| cache: false
|
||
knitr::opts_chunk$set(echo = TRUE)
|
||
source("../../coding/_common.R")
|
||
require(learnr)
|
||
library(tidyverse)
|
||
library(palmerpenguins)
|
||
library(ggthemes)
|
||
```
|
||
|
||
|
||
|
||
## {background-image="../../img/concepts/tidyverse-packages-ggplot.png" background-position="center" background-size="100%"}
|
||
|
||
|
||
|
||
## The ggplot2 Package
|
||
|
||
<br>
|
||
|
||
... is an **R package to visualize data** created by Hadley Wickham in 2005
|
||
|
||
```{r}
|
||
#| label: ggplot-package-install-2
|
||
#| eval: false
|
||
# install.packages("ggplot2")
|
||
library(ggplot2)
|
||
```
|
||
|
||
<br>
|
||
|
||
::: fragment
|
||
... is part of the [`{tidyverse}`](https://www.tidyverse.org/)
|
||
|
||
```{r}
|
||
#| label: tidyverse-package-install-2
|
||
#| eval: false
|
||
# install.packages("tidyverse")
|
||
library(tidyverse)
|
||
```
|
||
:::
|
||
|
||
# The Grammar of {ggplot2}
|
||
|
||
|
||
|
||
## The Grammar of {ggplot2}
|
||
|
||
<br>
|
||
<table style='width:100%;font-size:14pt;'>
|
||
<tr>
|
||
<th>Component</th>
|
||
<th>Function</th>
|
||
<th>Explanation</th>
|
||
</tr>
|
||
<tr>
|
||
<td><b style='color:#67676;'>Data</b></td>
|
||
<td><code>ggplot(data)</code> </td>
|
||
<td>*The raw data that you want to visualise.*</td>
|
||
</tr>
|
||
<tr>
|
||
<td><b style='color:#67676;'>Aesthetics </b></td>
|
||
<td><code>aes()</code></td>
|
||
<td>*Aesthetic mappings between variables and visual properties.*</td>
|
||
<tr>
|
||
<td><b style='color:#67676;'>Geometries</b></td>
|
||
<td><code>geom_*()</code></td>
|
||
<td>*The geometric shapes representing the data.*</td>
|
||
</tr>
|
||
</table>
|
||
|
||
|
||
|
||
## The Grammar of {ggplot2}
|
||
|
||
|
||
<br>
|
||
<table style='width:100%;font-size:14pt;'>
|
||
<tr>
|
||
<th>Component</th>
|
||
<th>Function</th>
|
||
<th>Explanation</th>
|
||
</tr>
|
||
<tr>
|
||
<td><b style='color:#67676;'>Data</b></td>
|
||
<td><code>ggplot(data)</code> </td>
|
||
<td>*The raw data that you want to visualise.*</td>
|
||
</tr>
|
||
<tr>
|
||
<td><b style='color:#67676;'>Aesthetics </b></td>
|
||
<td><code>aes()</code></td>
|
||
<td>*Aesthetic mappings between variables and visual properties.*</td>
|
||
<tr>
|
||
<td><b style='color:#67676;'>Geometries</b></td>
|
||
<td><code>geom_*()</code></td>
|
||
<td>*The geometric shapes representing the data.*</td>
|
||
</tr>
|
||
<tr>
|
||
<td><b style='color:#67676;'>Statistics</b></td>
|
||
<td><code>stat_*()</code></td>
|
||
<td>*The statistical transformations applied to the data.*</td>
|
||
</tr>
|
||
<tr>
|
||
<td><b style='color:#67676;'>Scales</b></td>
|
||
<td><code>scale_*()</code></td>
|
||
<td>*Maps between the data and the aesthetic dimensions.*</td>
|
||
</tr>
|
||
<tr>
|
||
<td><b style='color:#67676;'>Coordinate System</b></td>
|
||
<td><code>coord_*()</code></td>
|
||
<td>*Maps data into the plane of the data rectangle.*</td>
|
||
</tr>
|
||
<tr>
|
||
<td><b style='color:#67676;'>Facets</b></td>
|
||
<td><code>facet_*()</code></td>
|
||
<td>*The arrangement of the data into a grid of plots.*</td>
|
||
</tr>
|
||
<tr>
|
||
<td><b style='color:#67676;'>Visual Themes</b></td>
|
||
<td><code>theme() / theme_*()</code></td>
|
||
<td>*The overall visual defaults of a plot.*</td>
|
||
</tr>
|
||
</table>
|
||
|
||
|
||
|
||
## The Data
|
||
|
||
<b style='font-size:2.3rem;'>Bike sharing counts in London, UK, powered by [TfL Open Data](https://tfl.gov.uk/modes/cycling/santander-cycles)</b>
|
||
|
||
::: incremental
|
||
- covers the years 2015 and 2016
|
||
- incl. weather data acquired from [freemeteo.com](https://freemeteo.com)
|
||
- prepared by Hristo Mavrodiev for [Kaggle](https://www.kaggle.com/hmavrodiev/london-bike-sharing-dataset)
|
||
:::
|
||
|
||
<br>
|
||
|
||
::: fragment
|
||
```{r}
|
||
#| label: data-import
|
||
bikes <- readr::read_csv("../../data/ggplot2/london-bikes-custom.csv",
|
||
## or: "https://raw.githubusercontent.com/z3tt/graphic-design-ggplot2/main/data/london-bikes-custom.csv"
|
||
col_types = "Dcfffilllddddc"
|
||
)
|
||
|
||
bikes$season <- forcats::fct_inorder(bikes$season)
|
||
```
|
||
:::
|
||
|
||
------------------------------------------------------------------------
|
||
|
||
```{r}
|
||
#| label: data-table
|
||
#| echo: false
|
||
#| purl: false
|
||
library(tidyverse)
|
||
tibble(
|
||
Variable = names(bikes),
|
||
Description = c(
|
||
"Date encoded as `YYYY-MM-DD`", "`day` (6:00am–5:59pm) or `night` (6:00pm–5:59am)", "`2015` or `2016`", "`1` (January) to `12` (December)", "`winter`, `spring`, `summer`, or `autumn`", "Sum of reported bikes rented", "`TRUE` being Monday to Friday and no bank holiday", "`TRUE` being Saturday or Sunday", "`TRUE` being a bank holiday in the UK", "Average air temperature (°C)", "Average feels like temperature (°C)", "Average air humidity (%)", "Average wind speed (km/h)", "Most common weather type"
|
||
),
|
||
Class = c(
|
||
"date", "character", "factor", "factor", "factor", "integer", "logical", "logical", "logical", "double", "double", "double", "double", "character"
|
||
)
|
||
) %>%
|
||
kableExtra::kbl(
|
||
booktabs = TRUE, longtable = TRUE
|
||
) %>%
|
||
kableExtra::kable_styling(
|
||
font_size = 20
|
||
) %>%
|
||
kableExtra::kable_minimal(
|
||
"hover", full_width = TRUE, position = "left", html_font = "Spline Sans Mono"
|
||
)
|
||
```
|
||
|
||
## `ggplot2::ggplot()`
|
||
|
||
```{r}
|
||
#| label: ggplot-function
|
||
#| eval: false
|
||
#| echo: false
|
||
#?ggplot
|
||
```
|
||
|
||
![](../../img/concepts/ggplot-fun-help.png){fig-alt="The help page of the ggplot() function." fig-width="175%"}
|
||
|
||
## Data
|
||
|
||
```{r}
|
||
#| label: setup-ggplot-slides
|
||
#| include: false
|
||
#| purl: false
|
||
library(ggplot2)
|
||
theme_set(theme_grey(base_size = 14))
|
||
```
|
||
|
||
```{r}
|
||
#| label: ggplot-data
|
||
#| output-location: column
|
||
ggplot(data = bikes)
|
||
```
|
||
|
||
## Aesthetic Mapping(视觉映射):`aes(.)`
|
||
|
||
<br>
|
||
|
||
<b class='simple-highlight-grn' style='font-size:2.6rem;'>= link variables to graphical properties</b><br><br>
|
||
|
||
::: incremental
|
||
- positions (`x`, `y`)
|
||
- colors (`color`, `fill`)
|
||
- shapes (`shape`, `linetype`)
|
||
- size (`size`)
|
||
- transparency (`alpha`)
|
||
- groupings (`group`)
|
||
:::
|
||
|
||
## Aesthetic Mapping(视觉映射):`aes(.)`
|
||
|
||
```{r}
|
||
#| label: ggplot-aesthetics-outside
|
||
#| output-location: column
|
||
#| code-line-numbers: "2|1,2"
|
||
ggplot(data = bikes) +
|
||
aes(x = temp_feel, y = count)
|
||
```
|
||
|
||
## <span style='color:#4758AB;'>aes</span>thetics
|
||
|
||
`aes()` outside as component
|
||
|
||
```{r}
|
||
#| label: ggplot-aesthetics-outside-comp
|
||
#| eval: false
|
||
ggplot(data = bikes) +
|
||
aes(x = temp_feel, y = count)
|
||
```
|
||
|
||
<br>
|
||
|
||
::: fragment
|
||
`aes()` inside, explicit matching
|
||
|
||
```{r}
|
||
#| label: ggplot-aesthetics-inside
|
||
#| eval: false
|
||
ggplot(data = bikes, mapping = aes(x = temp_feel, y = count))
|
||
```
|
||
|
||
<br>
|
||
:::
|
||
|
||
::: fragment
|
||
`aes()` inside, implicit matching
|
||
|
||
```{r}
|
||
#| label: ggplot-aesthetics-inside-implicit
|
||
#| eval: false
|
||
ggplot(bikes, aes(temp_feel, count))
|
||
```
|
||
|
||
<br>
|
||
:::
|
||
|
||
::: fragment
|
||
`aes()` inside, mixed matching
|
||
|
||
```{r}
|
||
#| label: ggplot-aesthetics-inside-mix
|
||
#| eval: false
|
||
ggplot(bikes, aes(x = temp_feel, y = count))
|
||
```
|
||
:::
|
||
|
||
# Geometrical Layers
|
||
|
||
## Geometries(几何图层):geom_*
|
||
|
||
<br>
|
||
|
||
<b class='simple-highlight-grn' style='font-size:2.6rem;'>= interpret aesthetics as graphical representations</b><br><br>
|
||
|
||
::: incremental
|
||
- points
|
||
- lines
|
||
- polygons
|
||
- text labels
|
||
- ...
|
||
:::
|
||
|
||
## Geometries(几何图层):geom_*
|
||
|
||
```{r}
|
||
#| label: geom-point
|
||
#| output-location: column
|
||
#| code-line-numbers: "1,2,3,4|5"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = count)
|
||
) +
|
||
geom_point()
|
||
```
|
||
|
||
## Visual Properties of Layers(图层属性)
|
||
|
||
```{r}
|
||
#| label: geom-point-properties
|
||
#| output-location: column
|
||
#| code-line-numbers: "5,6,7,8,9,10,11|6,7,8,9,10"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = count)
|
||
) +
|
||
geom_point(
|
||
color = "#28a87d",
|
||
alpha = .5,
|
||
shape = "X",
|
||
stroke = 1,
|
||
size = 4
|
||
)
|
||
```
|
||
|
||
## Setting vs Mapping of Visual Properties
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: geom-point-properties-set
|
||
#| fig-height: 3.5
|
||
#| code-line-numbers: "6"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = count)
|
||
) +
|
||
geom_point(
|
||
color = "#28a87d",
|
||
alpha = .5
|
||
)
|
||
```
|
||
|
||
::: fragment
|
||
```{r}
|
||
#| label: geom-point-properties-map
|
||
#| fig-height: 3.5
|
||
#| code-line-numbers: "6"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = count)
|
||
) +
|
||
geom_point(
|
||
aes(color = season),
|
||
alpha = .5
|
||
)
|
||
```
|
||
:::
|
||
:::
|
||
|
||
## Mapping Expressions
|
||
|
||
```{r}
|
||
#| label: geom-point-aes-expression
|
||
#| output-location: column
|
||
#| code-line-numbers: "6"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = count)
|
||
) +
|
||
geom_point(
|
||
aes(color = temp_feel > 20),
|
||
alpha = .5
|
||
)
|
||
```
|
||
|
||
## Filter Data
|
||
|
||
```{r}
|
||
#| label: geom-point-aes-expression-exercise-na
|
||
#| output-location: column
|
||
#| code-line-numbers: "2"
|
||
ggplot(
|
||
filter(bikes, !is.na(weather_type)),
|
||
aes(x = temp, y = temp_feel)
|
||
) +
|
||
geom_point(
|
||
aes(color = weather_type == "clear",
|
||
size = count),
|
||
shape = 18,
|
||
alpha = .5
|
||
)
|
||
```
|
||
|
||
## Filter Data
|
||
|
||
```{r}
|
||
#| label: geom-point-aes-expression-exercise-na-pipe
|
||
#| output-location: column
|
||
#| code-line-numbers: "2"
|
||
ggplot(
|
||
bikes %>% filter(!is.na(weather_type)),
|
||
aes(x = temp, y = temp_feel)
|
||
) +
|
||
geom_point(
|
||
aes(color = weather_type == "clear",
|
||
size = count),
|
||
shape = 18,
|
||
alpha = .5
|
||
)
|
||
```
|
||
|
||
```{r}
|
||
#| label: reset-theme
|
||
#| include: false
|
||
#| purl: false
|
||
theme_set(theme_grey(base_size = 14))
|
||
```
|
||
|
||
## Local vs. Global(应用至当前图层或所有图层)
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: geom-point-aes-geom
|
||
#| code-line-numbers: "3,6"
|
||
#| fig-height: 3.2
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = count)
|
||
) +
|
||
geom_point(
|
||
aes(color = season),
|
||
alpha = .5
|
||
)
|
||
```
|
||
|
||
::: fragment
|
||
```{r}
|
||
#| label: geom-point-aes-global
|
||
#| code-line-numbers: "3,4"
|
||
#| fig-height: 3.2
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point(
|
||
alpha = .5
|
||
)
|
||
```
|
||
:::
|
||
:::
|
||
|
||
## Adding More Layers
|
||
|
||
```{r}
|
||
#| label: geom-smooth
|
||
#| output-location: column
|
||
#| code-line-numbers: "9,10,11"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point(
|
||
alpha = .5
|
||
) +
|
||
geom_smooth(
|
||
method = "lm"
|
||
)
|
||
```
|
||
|
||
## Global Color Encoding
|
||
|
||
```{r}
|
||
#| label: geom-smooth-aes-global
|
||
#| output-location: column
|
||
#| code-line-numbers: "3,4,9,10,11"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point(
|
||
alpha = .5
|
||
) +
|
||
geom_smooth(
|
||
method = "lm"
|
||
)
|
||
```
|
||
|
||
## Local Color Encoding
|
||
|
||
```{r}
|
||
#| label: geom-smooth-aes-fixed
|
||
#| output-location: column
|
||
#| code-line-numbers: "6,9,10,11"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = count)
|
||
) +
|
||
geom_point(
|
||
aes(color = season),
|
||
alpha = .5
|
||
) +
|
||
geom_smooth(
|
||
method = "lm"
|
||
)
|
||
```
|
||
|
||
## The \`group\` Aesthetic
|
||
|
||
```{r}
|
||
#| label: geom-smooth-aes-grouped
|
||
#| output-location: column
|
||
#| code-line-numbers: "10"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = count)
|
||
) +
|
||
geom_point(
|
||
aes(color = season),
|
||
alpha = .5
|
||
) +
|
||
geom_smooth(
|
||
aes(group = day_night),
|
||
method = "lm"
|
||
)
|
||
```
|
||
|
||
## Set Both as Global Aesthetics
|
||
|
||
```{r}
|
||
#| label: geom-smooth-aes-global-grouped
|
||
#| output-location: column
|
||
#| code-line-numbers: "4,5"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = count,
|
||
color = season,
|
||
group = day_night)
|
||
) +
|
||
geom_point(
|
||
alpha = .5
|
||
) +
|
||
geom_smooth(
|
||
method = "lm"
|
||
)
|
||
```
|
||
|
||
## Overwrite Global Aesthetics
|
||
|
||
```{r}
|
||
#| label: geom-smooth-aes-global-grouped-overwrite
|
||
#| output-location: column
|
||
#| code-line-numbers: "4,12"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = count,
|
||
color = season,
|
||
group = day_night)
|
||
) +
|
||
geom_point(
|
||
alpha = .5
|
||
) +
|
||
geom_smooth(
|
||
method = "lm",
|
||
color = "black"
|
||
)
|
||
```
|
||
|
||
|
||
|
||
# Statistical Layers
|
||
|
||
|
||
## \`stat_\*()\` and \`geom_\*()\`
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: stat-geom
|
||
#| fig-height: 5.1
|
||
#| code-line-numbers: "2"
|
||
ggplot(bikes, aes(x = temp_feel, y = count)) +
|
||
stat_smooth(geom = "smooth")
|
||
```
|
||
|
||
```{r}
|
||
#| label: geom-stat
|
||
#| fig-height: 5.1
|
||
#| code-line-numbers: "2"
|
||
ggplot(bikes, aes(x = temp_feel, y = count)) +
|
||
geom_smooth(stat = "smooth")
|
||
```
|
||
:::
|
||
|
||
|
||
## \`stat_\*()\` and \`geom_\*()\`
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: stat-geom-2
|
||
#| fig-height: 5.1
|
||
#| code-line-numbers: "2"
|
||
ggplot(bikes, aes(x = season)) +
|
||
stat_count(geom = "bar")
|
||
```
|
||
|
||
```{r}
|
||
#| label: geom-stat-2
|
||
#| fig-height: 5.1
|
||
#| code-line-numbers: "2"
|
||
ggplot(bikes, aes(x = season)) +
|
||
geom_bar(stat = "count")
|
||
```
|
||
:::
|
||
|
||
|
||
## \`stat_\*()\` and \`geom_\*()\`
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: stat-geom-3
|
||
#| fig-height: 5.1
|
||
#| code-line-numbers: "2"
|
||
ggplot(bikes, aes(x = date, y = temp_feel)) +
|
||
stat_identity(geom = "point")
|
||
```
|
||
|
||
```{r}
|
||
#| label: geom-stat-3
|
||
#| fig-height: 5.1
|
||
#| code-line-numbers: "2"
|
||
ggplot(bikes, aes(x = date, y = temp_feel)) +
|
||
geom_point(stat = "identity")
|
||
```
|
||
:::
|
||
|
||
## Statistical Summaries
|
||
|
||
```{r}
|
||
#| label: stat-summary
|
||
#| output-location: column
|
||
#| code-line-numbers: "5|3"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = season, y = temp_feel)
|
||
) +
|
||
stat_summary()
|
||
```
|
||
|
||
|
||
## Statistical Summaries
|
||
|
||
```{r}
|
||
#| label: stat-summary-defaults
|
||
#| output-location: column
|
||
#| code-line-numbers: "6,7"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = season, y = temp_feel)
|
||
) +
|
||
stat_summary(
|
||
fun.data = mean_se, ## the default
|
||
geom = "pointrange" ## the default
|
||
)
|
||
```
|
||
|
||
|
||
## Statistical Summaries
|
||
|
||
```{r}
|
||
#| label: stat-summary-median
|
||
#| output-location: column
|
||
#| code-line-numbers: "5|5,6,11|6,7,8,9,10,11|7,8"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = season, y = temp_feel)
|
||
) +
|
||
geom_boxplot() +
|
||
stat_summary(
|
||
fun = mean,
|
||
geom = "point",
|
||
color = "#28a87d",
|
||
size = 3
|
||
)
|
||
```
|
||
|
||
|
||
## Statistical Summaries
|
||
|
||
```{r}
|
||
#| label: stat-summary-custom
|
||
#| output-location: column
|
||
#| code-line-numbers: "5,6,7,8,9|7,8"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = season, y = temp_feel)
|
||
) +
|
||
stat_summary(
|
||
fun = mean,
|
||
fun.max = function(y) mean(y) + sd(y),
|
||
fun.min = function(y) mean(y) - sd(y)
|
||
)
|
||
```
|
||
|
||
|
||
|
||
# Extending a ggplot
|
||
|
||
## Store a ggplot as Object
|
||
|
||
```{r}
|
||
#| label: ggplot-object
|
||
#| code-line-numbers: "1,16"
|
||
g <-
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = count,
|
||
color = season,
|
||
group = day_night)
|
||
) +
|
||
geom_point(
|
||
alpha = .5
|
||
) +
|
||
geom_smooth(
|
||
method = "lm",
|
||
color = "black"
|
||
)
|
||
|
||
class(g)
|
||
```
|
||
|
||
## Inspect a ggplot Object
|
||
|
||
```{r}
|
||
#| label: ggplot-object-data
|
||
g$data
|
||
```
|
||
|
||
## Inspect a ggplot Object
|
||
|
||
```{r}
|
||
#| label: ggplot-object-mapping
|
||
g$mapping
|
||
```
|
||
|
||
## Extend a ggplot Object: Add Layers
|
||
|
||
```{r}
|
||
#| label: ggplot-object-extend-geom
|
||
#| output-location: column
|
||
g +
|
||
geom_rug(
|
||
alpha = .2
|
||
)
|
||
```
|
||
|
||
## Remove a Layer from the Legend
|
||
|
||
```{r}
|
||
#| label: geom-guide-none
|
||
#| output-location: column
|
||
#| code-line-numbers: "4"
|
||
g +
|
||
geom_rug(
|
||
alpha = .2,
|
||
show.legend = FALSE
|
||
)
|
||
```
|
||
|
||
## Extend a ggplot Object: Add Labels
|
||
|
||
```{r}
|
||
#| label: ggplot-labs-individual
|
||
#| output-location: column
|
||
#| code-line-numbers: "2,3,4"
|
||
g +
|
||
xlab("Feels-like temperature (°F)") +
|
||
ylab("Reported bike shares") +
|
||
ggtitle("TfL bike sharing trends")
|
||
```
|
||
|
||
## Extend a ggplot Object: Add Labels
|
||
|
||
```{r}
|
||
#| label: ggplot-labs-bundled
|
||
#| output-location: column
|
||
#| code-line-numbers: "2,3,4,5,6"
|
||
g +
|
||
labs(
|
||
x = "Feels-like temperature (°F)",
|
||
y = "Reported bike shares",
|
||
title = "TfL bike sharing trends"
|
||
)
|
||
```
|
||
|
||
## Extend a ggplot Object: Add Labels
|
||
|
||
```{r}
|
||
#| label: ggplot-labs-bundled-color
|
||
#| output-location: column
|
||
#| code-line-numbers: "6"
|
||
g <- g +
|
||
labs(
|
||
x = "Feels-like temperature (°F)",
|
||
y = "Reported bike shares",
|
||
title = "TfL bike sharing trends",
|
||
color = "Season:"
|
||
)
|
||
|
||
g
|
||
```
|
||
|
||
## Extend a ggplot Object: Add Labels
|
||
|
||
```{r}
|
||
#| label: ggplot-labs-bundled-extended
|
||
#| output-location: column
|
||
#| code-line-numbers: "6,7,9"
|
||
g +
|
||
labs(
|
||
x = "Feels-like temperature (°F)",
|
||
y = "Reported bike shares",
|
||
title = "TfL bike sharing trends",
|
||
subtitle = "Reported bike rents versus feels-like temperature in London",
|
||
caption = "Data: TfL",
|
||
color = "Season:",
|
||
tag = "Fig. 1"
|
||
)
|
||
```
|
||
|
||
## Extend a ggplot Object: Add Labels
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: ggplot-labs-empty-vs-null-A
|
||
#| fig-height: 3.6
|
||
#| code-line-numbers: "3"
|
||
g +
|
||
labs(
|
||
x = "",
|
||
caption = "Data: TfL"
|
||
)
|
||
```
|
||
|
||
```{r}
|
||
#| label: ggplot-labs-empty-vs-null-B
|
||
#| fig-height: 3.6
|
||
#| code-line-numbers: "3"
|
||
g +
|
||
labs(
|
||
x = NULL,
|
||
caption = "Data: TfL"
|
||
)
|
||
```
|
||
:::
|
||
|
||
## Extend a ggplot Object: Themes
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: ggplot-object-extend-theme-light
|
||
#| fig-height: 5.5
|
||
g + theme_light()
|
||
```
|
||
|
||
::: fragment
|
||
```{r}
|
||
#| label: ggplot-object-extend-theme-minimal
|
||
#| fig-height: 5.5
|
||
g + theme_minimal()
|
||
```
|
||
:::
|
||
:::
|
||
|
||
## Change the Theme Base Settings
|
||
|
||
```{r}
|
||
#| label: ggplot-theme-extend-theme-base
|
||
#| output-location: column
|
||
#| code-line-numbers: "2,3|1,2,3,4"
|
||
g + theme_light(
|
||
base_size = 14
|
||
)
|
||
```
|
||
|
||
## Set a Theme Globally
|
||
|
||
```{r}
|
||
#| label: ggplot-theme-global
|
||
#| output-location: column
|
||
theme_set(theme_light())
|
||
|
||
g
|
||
```
|
||
|
||
## Change the Theme Base Settings
|
||
|
||
```{r}
|
||
#| label: ggplot-theme-global-base
|
||
#| output-location: column
|
||
#| code-line-numbers: "2,3|1,2,3,4"
|
||
theme_set(theme_light(
|
||
base_size = 14
|
||
))
|
||
|
||
g
|
||
```
|
||
|
||
|
||
## Overwrite Specific Theme Settings
|
||
|
||
```{r}
|
||
#| label: ggplot-theme-settings-individual-1
|
||
#| output-location: column
|
||
#| code-line-numbers: "2|3"
|
||
g +
|
||
theme(
|
||
panel.grid.minor = element_blank()
|
||
)
|
||
```
|
||
|
||
## Overwrite Specific Theme Settings
|
||
|
||
```{r}
|
||
#| label: ggplot-theme-settings-individual-2
|
||
#| output-location: column
|
||
#| code-line-numbers: "4"
|
||
g +
|
||
theme(
|
||
panel.grid.minor = element_blank(),
|
||
plot.title = element_text(face = "bold")
|
||
)
|
||
```
|
||
|
||
## Overwrite Specific Theme Settings
|
||
|
||
```{r}
|
||
#| label: ggplot-theme-settings-individual-3
|
||
#| output-location: column
|
||
#| code-line-numbers: "5"
|
||
g +
|
||
theme(
|
||
panel.grid.minor = element_blank(),
|
||
plot.title = element_text(face = "bold"),
|
||
legend.position = "top"
|
||
)
|
||
```
|
||
|
||
## Overwrite Specific Theme Settings
|
||
|
||
```{r}
|
||
#| label: ggplot-theme-settings-individual-legend-none
|
||
#| output-location: column
|
||
#| code-line-numbers: "5"
|
||
g +
|
||
theme(
|
||
panel.grid.minor = element_blank(),
|
||
plot.title = element_text(face = "bold"),
|
||
legend.position = "none"
|
||
)
|
||
```
|
||
|
||
## Overwrite Specific Theme Settings
|
||
|
||
```{r}
|
||
#| label: ggplot-theme-settings-individual-4
|
||
#| output-location: column
|
||
#| code-line-numbers: "6|2,3,4,6,7"
|
||
g +
|
||
theme(
|
||
panel.grid.minor = element_blank(),
|
||
plot.title = element_text(face = "bold"),
|
||
legend.position = "top",
|
||
plot.title.position = "plot"
|
||
)
|
||
```
|
||
|
||
## Overwrite Theme Settings Globally
|
||
|
||
```{r}
|
||
#| label: ggplot-theme-settings-global
|
||
#| output-location: column
|
||
#| code-line-numbers: "1|2,3,4,5|1,2,3,4,5,6"
|
||
theme_update(
|
||
panel.grid.minor = element_blank(),
|
||
plot.title = element_text(face = "bold"),
|
||
legend.position = "top",
|
||
plot.title.position = "plot"
|
||
)
|
||
|
||
g
|
||
```
|
||
|
||
## Save the Graphic
|
||
|
||
```{r}
|
||
#| label: ggplot-save
|
||
#| eval: false
|
||
ggsave(g, filename = "my_plot.png")
|
||
```
|
||
|
||
::: fragment
|
||
```{r}
|
||
#| label: ggplot-save-implicit
|
||
#| eval: false
|
||
ggsave("my_plot.png")
|
||
```
|
||
:::
|
||
|
||
::: fragment
|
||
```{r}
|
||
#| label: ggplot-save-aspect
|
||
#| eval: false
|
||
ggsave("my_plot.png", width = 8, height = 5, dpi = 600)
|
||
```
|
||
:::
|
||
|
||
::: fragment
|
||
```{r}
|
||
#| label: ggplot-save-vector
|
||
#| eval: false
|
||
ggsave("my_plot.pdf", width = 20, height = 12, unit = "cm", device = cairo_pdf)
|
||
```
|
||
:::
|
||
|
||
::: fragment
|
||
```{r}
|
||
#| label: ggplot-save-cairo_pdf
|
||
#| eval: false
|
||
grDevices::cairo_pdf("my_plot.pdf", width = 10, height = 7)
|
||
g
|
||
dev.off()
|
||
```
|
||
:::
|
||
|
||
------------------------------------------------------------------------
|
||
|
||
<br>
|
||
|
||
![Modified from canva.com](../../img/concepts/vector-raster-canva.png){fig-alt="A comparison of vector and raster graphics." fig-width="150%"}
|
||
|
||
# Facets(面)
|
||
|
||
## Facets(面)
|
||
|
||
<br>
|
||
|
||
<b class='simple-highlight-grn' style='font-size:2.6rem;'>= split variables to multiple panels</b><br><br>
|
||
|
||
::: fragment
|
||
Facets are also known as:
|
||
|
||
- small multiples
|
||
- trellis graphs
|
||
- lattice plots
|
||
- conditioning
|
||
:::
|
||
|
||
------------------------------------------------------------------------
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: facet-types-wrap
|
||
#| echo: false
|
||
#| purl: false
|
||
ggplot(bikes, aes(x = 1, y = 1)) +
|
||
geom_text(
|
||
aes(label = paste0("Subset for\n", stringr::str_to_title(season))),
|
||
size = 5, family = "Cabinet Grotesk", lineheight = .9
|
||
) +
|
||
facet_wrap(~stringr::str_to_title(season)) +
|
||
ggtitle("facet_wrap()") +
|
||
theme_bw(base_size = 24) +
|
||
theme(
|
||
plot.title = element_text(hjust = .5, family = "Tabular", face = "bold"),
|
||
strip.text = element_text(face = "bold", size = 18),
|
||
panel.grid = element_blank(),
|
||
axis.ticks = element_blank(),
|
||
axis.text = element_blank(),
|
||
axis.title = element_blank(),
|
||
plot.background = element_rect(color = "#f8f8f8", fill = "#f8f8f8"),
|
||
plot.margin = margin(t = 3, r = 25)
|
||
)
|
||
```
|
||
|
||
::: fragment
|
||
```{r}
|
||
#| label: facet-types-grid
|
||
#| echo: false
|
||
#| purl: false
|
||
data <- tibble(
|
||
x = 1, y = 1,
|
||
day_night = c("Day", "Day", "Night", "Night"),
|
||
year = factor(c("2015", "2016", "2015", "2016"), levels = levels(bikes$year)),
|
||
label = c("Subset for\nDay × 2015", "Subset for\nDay × 2016",
|
||
"Subset for\nNight × 2015", "Subset for\nNight × 2016")
|
||
)
|
||
|
||
ggplot(data, aes(x = 1, y = 1)) +
|
||
geom_text(
|
||
aes(label = label),
|
||
size = 5, family = "Cabinet Grotesk", lineheight = .9
|
||
) +
|
||
facet_grid(day_night ~ year) +
|
||
ggtitle("facet_grid()") +
|
||
theme_bw(base_size = 24) +
|
||
theme(
|
||
plot.title = element_text(hjust = .5, family = "Tabular", face = "bold"),
|
||
strip.text = element_text(face = "bold", size = 18),
|
||
panel.grid = element_blank(),
|
||
axis.ticks = element_blank(),
|
||
axis.text = element_blank(),
|
||
axis.title = element_blank(),
|
||
plot.background = element_rect(color = "#f8f8f8", fill = "#f8f8f8"),
|
||
plot.margin = margin(t = 3, l = 25)
|
||
)
|
||
```
|
||
:::
|
||
:::
|
||
|
||
## Setup
|
||
|
||
```{r}
|
||
#| label: theme-size-facets
|
||
#| include: false
|
||
#| purl: false
|
||
theme_set(theme_light(base_size = 12))
|
||
|
||
theme_update(
|
||
panel.grid.minor = element_blank(),
|
||
plot.title = element_text(face = "bold"),
|
||
legend.position = "top",
|
||
plot.title.position = "plot"
|
||
)
|
||
```
|
||
|
||
```{r}
|
||
#| label: facet-setup
|
||
#| output-location: column
|
||
#| code-line-numbers: "1,2,3,4,5,6,7,8,9,10|12"
|
||
g <-
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point(
|
||
alpha = .3,
|
||
guide = "none"
|
||
)
|
||
|
||
g
|
||
```
|
||
|
||
## Wrapped Facets
|
||
|
||
```{r}
|
||
#| label: facet-wrap
|
||
#| output-location: column
|
||
#| code-line-numbers: "1,2,3,4|2,4|3"
|
||
g +
|
||
facet_wrap(
|
||
vars(day_night)
|
||
)
|
||
```
|
||
|
||
## Wrapped Facets
|
||
|
||
```{r}
|
||
#| label: facet-wrap-circumflex
|
||
#| output-location: column
|
||
#| code-line-numbers: "3"
|
||
g +
|
||
facet_wrap(
|
||
~ day_night
|
||
)
|
||
```
|
||
|
||
## Facet Multiple Variables
|
||
|
||
```{r}
|
||
#| label: facet-wrap-multiple
|
||
#| output-location: column
|
||
#| code-line-numbers: "3"
|
||
g +
|
||
facet_wrap(
|
||
~ is_workday + day_night
|
||
)
|
||
```
|
||
|
||
## Facet Options: Cols + Rows
|
||
|
||
```{r}
|
||
#| label: facet-wrap-options-ncol
|
||
#| output-location: column
|
||
#| code-line-numbers: "4"
|
||
g +
|
||
facet_wrap(
|
||
~ day_night,
|
||
ncol = 1
|
||
)
|
||
```
|
||
|
||
## Facet Options: Free Scaling
|
||
|
||
```{r}
|
||
#| label: facet-wrap-options-scales
|
||
#| output-location: column
|
||
#| code-line-numbers: "5"
|
||
g +
|
||
facet_wrap(
|
||
~ day_night,
|
||
ncol = 1,
|
||
scales = "free"
|
||
)
|
||
```
|
||
|
||
## Facet Options: Free Scaling
|
||
|
||
```{r}
|
||
#| label: facet-wrap-options-freey
|
||
#| output-location: column
|
||
#| code-line-numbers: "5"
|
||
g +
|
||
facet_wrap(
|
||
~ day_night,
|
||
ncol = 1,
|
||
scales = "free_y"
|
||
)
|
||
```
|
||
|
||
## Facet Options: Switch Labels
|
||
|
||
```{r}
|
||
#| label: facet-wrap-options-switch
|
||
#| output-location: column
|
||
#| code-line-numbers: "5"
|
||
g +
|
||
facet_wrap(
|
||
~ day_night,
|
||
ncol = 1,
|
||
switch = "x"
|
||
)
|
||
```
|
||
|
||
## Gridded Facets
|
||
|
||
```{r}
|
||
#| label: facet-grid
|
||
#| output-location: column
|
||
#| code-line-numbers: "2,5|3,4"
|
||
g +
|
||
facet_grid(
|
||
rows = vars(day_night),
|
||
cols = vars(is_workday)
|
||
)
|
||
```
|
||
|
||
## Gridded Facets
|
||
|
||
```{r}
|
||
#| label: facet-grid-circumflex
|
||
#| output-location: column
|
||
#| code-line-numbers: "3"
|
||
g +
|
||
facet_grid(
|
||
day_night ~ is_workday
|
||
)
|
||
```
|
||
|
||
## Facet Multiple Variables
|
||
|
||
```{r}
|
||
#| label: facet-grid-multiple
|
||
#| output-location: column
|
||
#| code-line-numbers: "3"
|
||
g +
|
||
facet_grid(
|
||
day_night ~ is_workday + season
|
||
)
|
||
```
|
||
|
||
## Facet Options: Free Scaling
|
||
|
||
```{r}
|
||
#| label: facet-grid-options-scales
|
||
#| output-location: column
|
||
#| code-line-numbers: "4"
|
||
g +
|
||
facet_grid(
|
||
day_night ~ is_workday,
|
||
scales = "free"
|
||
)
|
||
```
|
||
|
||
## Facet Options: Switch Labels
|
||
|
||
```{r}
|
||
#| label: facet-grid-options-switch
|
||
#| output-location: column
|
||
#| code-line-numbers: "5"
|
||
g +
|
||
facet_grid(
|
||
day_night ~ is_workday,
|
||
scales = "free",
|
||
switch = "y"
|
||
)
|
||
```
|
||
|
||
## Facet Options: Proportional Spacing
|
||
|
||
```{r}
|
||
#| label: facet-grid-options-space
|
||
#| output-location: column
|
||
#| code-line-numbers: "4,5|5"
|
||
g +
|
||
facet_grid(
|
||
day_night ~ is_workday,
|
||
scales = "free",
|
||
space = "free"
|
||
)
|
||
```
|
||
|
||
## Facet Options: Proportional Spacing
|
||
|
||
```{r}
|
||
#| label: facet-grid-options-space-y
|
||
#| output-location: column
|
||
#| code-line-numbers: "4,5"
|
||
g +
|
||
facet_grid(
|
||
day_night ~ is_workday,
|
||
scales = "free_y",
|
||
space = "free_y"
|
||
)
|
||
```
|
||
|
||
## Diamonds Facet
|
||
|
||
```{r}
|
||
#| label: diamonds-facet-start
|
||
#| output-location: column
|
||
#| code-line-numbers: "1,2,3,4,5,6,7,8,9,10,11,12|8,9,10"
|
||
ggplot(
|
||
diamonds,
|
||
aes(x = carat, y = price)
|
||
) +
|
||
geom_point(
|
||
alpha = .3
|
||
) +
|
||
geom_smooth(
|
||
method = "lm",
|
||
se = FALSE,
|
||
color = "dodgerblue"
|
||
)
|
||
```
|
||
|
||
## Diamonds Facet
|
||
|
||
```{r}
|
||
#| label: diamonds-facet
|
||
#| output-location: column
|
||
#| code-line-numbers: "13,14,15,16,17"
|
||
ggplot(
|
||
diamonds,
|
||
aes(x = carat, y = price)
|
||
) +
|
||
geom_point(
|
||
alpha = .3
|
||
) +
|
||
geom_smooth(
|
||
method = "lm",
|
||
se = FALSE,
|
||
color = "dodgerblue"
|
||
) +
|
||
facet_grid(
|
||
cut ~ clarity,
|
||
space = "free_x",
|
||
scales = "free_x"
|
||
)
|
||
```
|
||
|
||
## Diamonds Facet (Dark Theme Bonus)
|
||
|
||
```{r}
|
||
#| label: diamonds-facet-dark
|
||
#| output-location: column
|
||
#| code-line-numbers: "19,20,21,22"
|
||
ggplot(
|
||
diamonds,
|
||
aes(x = carat, y = price)
|
||
) +
|
||
geom_point(
|
||
alpha = .3,
|
||
color = "white"
|
||
) +
|
||
geom_smooth(
|
||
method = "lm",
|
||
se = FALSE,
|
||
color = "dodgerblue"
|
||
) +
|
||
facet_grid(
|
||
cut ~ clarity,
|
||
space = "free_x",
|
||
scales = "free_x"
|
||
) +
|
||
theme_dark(
|
||
base_size = 14
|
||
)
|
||
```
|
||
|
||
# Scales(尺度)
|
||
|
||
```{r}
|
||
#| label: theme-size-reset
|
||
#| include: false
|
||
#| purl: false
|
||
theme_set(theme_light(base_size = 14))
|
||
|
||
theme_update(
|
||
panel.grid.minor = element_blank(),
|
||
plot.title = element_text(face = "bold"),
|
||
legend.position = "top",
|
||
plot.title.position = "plot"
|
||
)
|
||
```
|
||
|
||
## Scales
|
||
|
||
<br>
|
||
|
||
<b class='simple-highlight-grn' style='font-size:2.6rem;'>= translate between variable ranges and property ranges</b><br><br>
|
||
|
||
::: incremental
|
||
- feels-like temperature ⇄ x
|
||
- reported bike shares ⇄ y
|
||
- season ⇄ color
|
||
- year ⇄ shape
|
||
- ...
|
||
:::
|
||
|
||
## Scales
|
||
|
||
The `scale_*()` components control the properties of all the<br><b class='simple-highlight-ylw'>aesthetic dimensions mapped to the data.</b>
|
||
|
||
<br>Consequently, there are `scale_*()` functions for all aesthetics such as:
|
||
|
||
- **positions** via `scale_x_*()` and `scale_y_*()`
|
||
|
||
- **colors** via `scale_color_*()` and `scale_fill_*()`
|
||
|
||
- **sizes** via `scale_size_*()` and `scale_radius_*()`
|
||
|
||
- **shapes** via `scale_shape_*()` and `scale_linetype_*()`
|
||
|
||
- **transparency** via `scale_alpha_*()`
|
||
|
||
## Scales
|
||
|
||
The `scale_*()` components control the properties of all the<br><b class='simple-highlight-ylw'>aesthetic dimensions mapped to the data.</b>
|
||
|
||
<br>The extensions (`*`) can be filled by e.g.:
|
||
|
||
- `continuous()`, `discrete()`, `reverse()`, `log10()`, `sqrt()`, `date()` for positions
|
||
|
||
- `continuous()`, `discrete()`, `manual()`, `gradient()`, `gradient2()`, `brewer()` for colors
|
||
|
||
- `continuous()`, `discrete()`, `manual()`, `ordinal()`, `area()`, `date()` for sizes
|
||
|
||
- `continuous()`, `discrete()`, `manual()`, `ordinal()` for shapes
|
||
|
||
- `continuous()`, `discrete()`, `manual()`, `ordinal()`, `date()` for transparency
|
||
|
||
------------------------------------------------------------------------
|
||
|
||
![Illustration by [Allison Horst](https://github.com/allisonhorst/stats-illustrations)](../../img/concepts/continuous_discrete.png){fig-size="120%" fig-align="center" fig-alt="Allison Horsts illustration ofthe correct use of continuous versus discrete; however, in {ggplot2} these are interpeted in a different way: as quantitative and qualitative."}
|
||
|
||
## Continuous vs. Discrete in {ggplot2}
|
||
|
||
::: {layout-ncol="2"}
|
||
## Continuous:<br>quantitative or numerical data
|
||
|
||
- height
|
||
- weight
|
||
- age
|
||
- counts
|
||
|
||
## Discrete:<br>qualitative or categorical data
|
||
|
||
- species
|
||
- sex
|
||
- study sites
|
||
- age group
|
||
:::
|
||
|
||
## Continuous vs. Discrete in {ggplot2}
|
||
|
||
::: {layout-ncol="2"}
|
||
## Continuous:<br>quantitative or numerical data
|
||
|
||
- height (continuous)
|
||
- weight (continuous)
|
||
- age (continuous or discrete)
|
||
- counts (discrete)
|
||
|
||
## Discrete:<br>qualitative or categorical data
|
||
|
||
- species (nominal)
|
||
- sex (nominal)
|
||
- study site (nominal or ordinal)
|
||
- age group (ordinal)
|
||
:::
|
||
|
||
## Aesthetics + Scales
|
||
|
||
```{r}
|
||
#| label: scales-default-invisible
|
||
#| output-location: column
|
||
#| code-line-numbers: "3,4"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point()
|
||
```
|
||
|
||
## Aesthetics + Scales
|
||
|
||
```{r}
|
||
#| label: scales-default
|
||
#| output-location: column
|
||
#| code-line-numbers: "3,4,7,8,9|7,8,9"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_x_date() +
|
||
scale_y_continuous() +
|
||
scale_color_discrete()
|
||
```
|
||
|
||
## Scales
|
||
|
||
```{r}
|
||
#| label: scales-overwrite-1
|
||
#| output-location: column
|
||
#| code-line-numbers: "7"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_x_continuous() +
|
||
scale_y_continuous() +
|
||
scale_color_discrete()
|
||
```
|
||
|
||
## Scales
|
||
|
||
```{r}
|
||
#| label: scales-overwrite-2
|
||
#| output-location: column
|
||
#| code-line-numbers: "8"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_x_continuous() +
|
||
scale_y_log10() +
|
||
scale_color_discrete()
|
||
```
|
||
|
||
## Scales
|
||
|
||
```{r}
|
||
#| label: scales-overwrite-3
|
||
#| output-location: column
|
||
#| code-line-numbers: "9"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_x_continuous() +
|
||
scale_y_log10() +
|
||
scale_color_viridis_d()
|
||
```
|
||
|
||
## \`scale_x\|y_continuous\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-continuous-trans
|
||
#| output-location: column
|
||
#| code-line-numbers: "8,9,10|9"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_y_continuous(
|
||
trans = "log10"
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_continuous\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-continuous-name
|
||
#| output-location: column
|
||
#| code-line-numbers: "7,8,9|8"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_y_continuous(
|
||
name = "Reported bike shares"
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_continuous\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-continuous-breaks-seq
|
||
#| output-location: column
|
||
#| code-line-numbers: "9"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_y_continuous(
|
||
name = "Reported bike shares",
|
||
breaks = seq(0, 60000, by = 15000)
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_continuous\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-continuous-breaks-short
|
||
#| output-location: column
|
||
#| code-line-numbers: "9"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_y_continuous(
|
||
name = "Reported bike shares",
|
||
breaks = 0:4*15000
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_continuous\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-continuous-breaks-irregular
|
||
#| output-location: column
|
||
#| code-line-numbers: "9"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_y_continuous(
|
||
name = "Reported bike shares",
|
||
breaks = c(0, 2:12*2500, 40000, 50000)
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_continuous\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-continuous-labels
|
||
#| output-location: column
|
||
#| code-line-numbers: "8,10"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_y_continuous(
|
||
name = "Reported bike shares in thousands",
|
||
breaks = 0:4*15000,
|
||
labels = 0:4*15
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_continuous\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-continuous-labels-paste
|
||
#| output-location: column
|
||
#| code-line-numbers: "10"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_y_continuous(
|
||
name = "Reported bike shares in thousands",
|
||
breaks = 0:4*15000,
|
||
labels = paste(0:4*15000, "bikes")
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_continuous\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-continuous-limits
|
||
#| output-location: column
|
||
#| code-line-numbers: "10"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_y_continuous(
|
||
name = "Reported bike shares",
|
||
breaks = 0:4*15000,
|
||
limits = c(NA, 60000)
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_continuous\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-continuous-expand.no
|
||
#| output-location: column
|
||
#| code-line-numbers: "10"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_y_continuous(
|
||
name = "Reported bike shares",
|
||
breaks = 0:4*15000,
|
||
expand = c(0, 0)
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_continuous\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-continuous-expand
|
||
#| output-location: column
|
||
#| code-line-numbers: "10"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_y_continuous(
|
||
name = "Reported bike shares",
|
||
breaks = -1:5*15000,
|
||
expand = c(.5, .5) ## c(add, mult)
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_continuous\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-continuous-expand-add-explicit
|
||
#| output-location: column
|
||
#| code-line-numbers: "10"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_y_continuous(
|
||
name = "Reported bike shares",
|
||
breaks = -1:5*15000,
|
||
expand = expansion(add = 2000)
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_continuous\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-continuous-guide-none
|
||
#| output-location: column
|
||
#| code-line-numbers: "10"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_y_continuous(
|
||
name = "Reported bike shares",
|
||
breaks = 0:4*15000,
|
||
guide = "none"
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_date\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-date-breaks-months
|
||
#| output-location: column
|
||
#| code-line-numbers: "7,10|7,8,9,10|9"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_x_date(
|
||
name = NULL,
|
||
date_breaks = "4 months"
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_date\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-date-breaks-weeks
|
||
#| output-location: column
|
||
#| code-line-numbers: "9"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_x_date(
|
||
name = NULL,
|
||
date_breaks = "20 weeks"
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_date\` with \`strftime()\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-date-labels
|
||
#| output-location: column
|
||
#| code-line-numbers: "9,10"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_x_date(
|
||
name = NULL,
|
||
date_breaks = "6 months",
|
||
date_labels = "%Y/%m/%d"
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_date\` with \`strftime()\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-date-labels-special
|
||
#| output-location: column
|
||
#| code-line-numbers: "10"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_x_date(
|
||
name = NULL,
|
||
date_breaks = "6 months",
|
||
date_labels = "%b '%y"
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_discrete\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-discrete
|
||
#| output-location: column
|
||
#| code-line-numbers: "3,6,9|6,7,8,9|7,8"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = season, y = count)
|
||
) +
|
||
geom_boxplot() +
|
||
scale_x_discrete(
|
||
name = "Period",
|
||
labels = c("Dec-Feb", "Mar-May", "Jun-Aug", "Sep-Nov")
|
||
)
|
||
```
|
||
|
||
## \`scale_x\|y_discrete\`
|
||
|
||
```{r}
|
||
#| label: scales-xy-discrete-expand
|
||
#| output-location: column
|
||
#| code-line-numbers: "8"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = season, y = count)
|
||
) +
|
||
geom_boxplot() +
|
||
scale_x_discrete(
|
||
name = "Season",
|
||
expand = c(.5, 0) ## add, mult
|
||
)
|
||
```
|
||
|
||
## Discrete or Continuous?
|
||
|
||
```{r}
|
||
#| label: scales-xy-fake-discrete-visible
|
||
#| output-location: column
|
||
#| code-line-numbers: "3,5,6,7"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = as.numeric(season), y = count)
|
||
) +
|
||
geom_boxplot(
|
||
aes(group = season)
|
||
)
|
||
```
|
||
|
||
## Discrete or Continuous?
|
||
|
||
```{r}
|
||
#| label: scales-xy-fake-discrete
|
||
#| output-location: column
|
||
#| code-line-numbers: "9,10,11,12,13|11|12"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = as.numeric(season),
|
||
y = count)
|
||
) +
|
||
geom_boxplot(
|
||
aes(group = season)
|
||
) +
|
||
scale_x_continuous(
|
||
name = "Season",
|
||
breaks = 1:4,
|
||
labels = levels(bikes$season)
|
||
)
|
||
```
|
||
|
||
## Discrete or Continuous?
|
||
|
||
```{r}
|
||
#| label: scales-xy-fake-discrete-shift
|
||
#| output-location: column
|
||
#| code-line-numbers: "3,4"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = as.numeric(season) +
|
||
as.numeric(season) / 8,
|
||
y = count)
|
||
) +
|
||
geom_boxplot(
|
||
aes(group = season)
|
||
) +
|
||
scale_x_continuous(
|
||
name = "Season",
|
||
breaks = 1:4,
|
||
labels = levels(bikes$season)
|
||
)
|
||
```
|
||
|
||
## \`scale_color\|fill_discrete\`
|
||
|
||
```{r}
|
||
#| label: scales-color-discrete-type-vector
|
||
#| output-location: column
|
||
#| code-line-numbers: "7,10|7,8,9,10|8,9"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_color_discrete(
|
||
name = "Season:",
|
||
type = c("#69b0d4", "#00CB79", "#F7B01B", "#a78f5f")
|
||
)
|
||
```
|
||
|
||
## Inspect Assigned Colors
|
||
|
||
```{r}
|
||
#| label: scales-color-discrete-type-inspect
|
||
#| output-location: column
|
||
#| code-line-numbers: "1|12|14"
|
||
g <- ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_color_discrete(
|
||
name = "Season:",
|
||
type = c("#3ca7d9", "#1ec99b", "#F7B01B", "#bb7e8f")
|
||
)
|
||
|
||
gb <- ggplot_build(g)
|
||
|
||
gb$data[[1]][c(1:5, 200:205, 400:405), 1:5]
|
||
```
|
||
|
||
## \`scale_color\|fill_discrete\`
|
||
|
||
```{r}
|
||
#| label: scales-color-discrete-type-vector-named
|
||
#| output-location: column
|
||
#| code-line-numbers: "1,2,3,4,5,6|1,16"
|
||
my_colors <- c(
|
||
`winter` = "#3c89d9",
|
||
`spring` = "#1ec99b",
|
||
`summer` = "#F7B01B",
|
||
`autumn` = "#a26e7c"
|
||
)
|
||
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_color_discrete(
|
||
name = "Season:",
|
||
type = my_colors
|
||
)
|
||
```
|
||
|
||
## \`scale_color\|fill_discrete\`
|
||
|
||
```{r}
|
||
#| label: scales-color-discrete-type-vector-named-shuffled
|
||
#| output-location: column
|
||
#| code-line-numbers: "2,5|1,16"
|
||
my_colors_alphabetical <- c(
|
||
`autumn` = "#a26e7c",
|
||
`spring` = "#1ec99b",
|
||
`summer` = "#F7B01B",
|
||
`winter` = "#3c89d9"
|
||
)
|
||
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_color_discrete(
|
||
name = "Season:",
|
||
type = my_colors_alphabetical
|
||
)
|
||
```
|
||
|
||
## \`scale_color\|fill_discrete\`
|
||
|
||
```{r}
|
||
#| label: scales-color-discrete-type-palette
|
||
#| output-location: column
|
||
#| code-line-numbers: "1|11,12,13"
|
||
library(RColorBrewer)
|
||
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = season)
|
||
) +
|
||
geom_point() +
|
||
scale_color_discrete(
|
||
name = "Season:",
|
||
type = brewer.pal(
|
||
n = 4, name = "Dark2"
|
||
)
|
||
)
|
||
```
|
||
|
||
## \`scale_color\|fill_manual\`
|
||
|
||
```{r}
|
||
#| label: scales-color-manual-na
|
||
#| output-location: column
|
||
#| code-line-numbers: "4,9,10"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = weather_type)
|
||
) +
|
||
geom_point() +
|
||
scale_color_manual(
|
||
name = "Season:",
|
||
values = brewer.pal(n = 6, name = "Pastel1"),
|
||
na.value = "black"
|
||
)
|
||
```
|
||
|
||
## \`scale_color\|fill_carto_d\`
|
||
|
||
```{r}
|
||
#| label: scales-color-discrete-carto
|
||
#| output-location: column
|
||
#| code-line-numbers: "7,8,9,10"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = date, y = count,
|
||
color = weather_type)
|
||
) +
|
||
geom_point() +
|
||
rcartocolor::scale_color_carto_d(
|
||
name = "Season:",
|
||
palette = "Pastel",
|
||
na.value = "black"
|
||
)
|
||
```
|
||
|
||
## Diamonds Facet
|
||
|
||
```{r}
|
||
#| label: diamonds-facet-store
|
||
#| output-location: column
|
||
#| code-line-numbers: "1|10|20"
|
||
facet <-
|
||
ggplot(
|
||
diamonds,
|
||
aes(x = carat, y = price)
|
||
) +
|
||
geom_point(
|
||
alpha = .3
|
||
) +
|
||
geom_smooth(
|
||
aes(color = cut),
|
||
method = "lm",
|
||
se = FALSE
|
||
) +
|
||
facet_grid(
|
||
cut ~ clarity,
|
||
space = "free_x",
|
||
scales = "free_x"
|
||
)
|
||
|
||
facet
|
||
```
|
||
|
||
## Diamonds Facet
|
||
|
||
```{r}
|
||
#| label: diamonds-facet-scales-xy
|
||
#| output-location: column
|
||
facet +
|
||
scale_x_continuous(
|
||
breaks = 0:5
|
||
) +
|
||
scale_y_continuous(
|
||
limits = c(0, 30000),
|
||
breaks = 0:3*10000,
|
||
labels = c("$0", "$10,000", "$20,000", "$30,000")
|
||
)
|
||
```
|
||
|
||
## Diamonds Facet
|
||
|
||
```{r}
|
||
#| label: diamonds-facet-scales-y-paste-format
|
||
#| output-location: column
|
||
#| code-line-numbers: "8,9,10,11,12,13,14"
|
||
facet +
|
||
scale_x_continuous(
|
||
breaks = 0:5
|
||
) +
|
||
scale_y_continuous(
|
||
limits = c(0, 30000),
|
||
breaks = 0:3*10000,
|
||
labels = paste0(
|
||
"$", format(
|
||
0:3*10000,
|
||
big.mark = ",",
|
||
trim = TRUE
|
||
)
|
||
)
|
||
)
|
||
```
|
||
|
||
## Diamonds Facet
|
||
|
||
```{r}
|
||
#| label: diamonds-facet-scales-y-function
|
||
#| output-location: column
|
||
#| code-line-numbers: "8,9,10,11,12,13"
|
||
facet +
|
||
scale_x_continuous(
|
||
breaks = 0:5
|
||
) +
|
||
scale_y_continuous(
|
||
limits = c(0, 30000),
|
||
breaks = 0:3*10000,
|
||
labels = function(y) paste0(
|
||
"$", format(
|
||
y, big.mark = ",",
|
||
trim = TRUE
|
||
)
|
||
)
|
||
)
|
||
```
|
||
|
||
## Diamonds Facet
|
||
|
||
```{r}
|
||
#| label: diamonds-facet-scales-y-dollar-format
|
||
#| output-location: column
|
||
#| code-line-numbers: "8"
|
||
facet +
|
||
scale_x_continuous(
|
||
breaks = 0:5
|
||
) +
|
||
scale_y_continuous(
|
||
limits = c(0, 30000),
|
||
breaks = 0:3*10000,
|
||
labels = scales::dollar_format()
|
||
)
|
||
```
|
||
|
||
## Diamonds Facet
|
||
|
||
```{r}
|
||
#| label: diamonds-facet-scales-color
|
||
#| output-location: column
|
||
#| code-line-numbers: "10,11,12,13"
|
||
facet +
|
||
scale_x_continuous(
|
||
breaks = 0:5
|
||
) +
|
||
scale_y_continuous(
|
||
limits = c(0, 30000),
|
||
breaks = 0:3*10000,
|
||
labels = scales::dollar_format()
|
||
) +
|
||
scale_color_brewer(
|
||
palette = "Set2",
|
||
guide = "none"
|
||
)
|
||
```
|
||
|
||
## Diamonds Facet
|
||
|
||
```{r}
|
||
#| label: diamonds-facet-scales-no-legend
|
||
#| output-location: column
|
||
#| code-line-numbers: "13,14,15"
|
||
facet +
|
||
scale_x_continuous(
|
||
breaks = 0:5
|
||
) +
|
||
scale_y_continuous(
|
||
limits = c(0, 30000),
|
||
breaks = 0:3*10000,
|
||
labels = scales::dollar_format()
|
||
) +
|
||
scale_color_brewer(
|
||
palette = "Set2"
|
||
) +
|
||
theme(
|
||
legend.position = "none"
|
||
)
|
||
```
|
||
|
||
# Coordinate Systems(投影)
|
||
|
||
## Coordinate Systems
|
||
|
||
<br>
|
||
|
||
<b class='simple-highlight-grn' style='font-size:2.6rem;'>= interpret the position aesthetics</b><br><br>
|
||
|
||
::: incremental
|
||
- **linear coordinate systems:** preserve the geometrical shapes
|
||
- `coord_cartesian()`
|
||
- `coord_fixed()`
|
||
- `coord_flip()`
|
||
- **non-linear coordinate systems:** likely change the geometrical shapes
|
||
- `coord_polar()`
|
||
- `coord_map()` and `coord_sf()`
|
||
- `coord_trans()`
|
||
:::
|
||
|
||
## Cartesian Coordinate System
|
||
|
||
```{r}
|
||
#| label: coord-cartesian
|
||
#| output-location: column
|
||
#| code-line-numbers: "6"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = season, y = count)
|
||
) +
|
||
geom_boxplot() +
|
||
coord_cartesian()
|
||
```
|
||
|
||
## Cartesian Coordinate System
|
||
|
||
```{r}
|
||
#| label: coord-cartesian-zoom
|
||
#| output-location: column
|
||
#| code-line-numbers: "6,7,8"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = season, y = count)
|
||
) +
|
||
geom_boxplot() +
|
||
coord_cartesian(
|
||
ylim = c(NA, 15000)
|
||
)
|
||
```
|
||
|
||
## Changing Limits
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: coord-cartesian-ylim
|
||
#| fig-height: 3.5
|
||
#| code-line-numbers: "6,7,8"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = season, y = count)
|
||
) +
|
||
geom_boxplot() +
|
||
coord_cartesian(
|
||
ylim = c(NA, 15000)
|
||
)
|
||
```
|
||
|
||
```{r}
|
||
#| label: scale-y-limits
|
||
#| fig-height: 3.5
|
||
#| code-line-numbers: "6,7,8"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = season, y = count)
|
||
) +
|
||
geom_boxplot() +
|
||
scale_y_continuous(
|
||
limits = c(NA, 15000)
|
||
)
|
||
```
|
||
:::
|
||
|
||
## Clipping
|
||
|
||
```{r}
|
||
#| label: coord-clip
|
||
#| output-location: column
|
||
#| code-line-numbers: "8"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = season, y = count)
|
||
) +
|
||
geom_boxplot() +
|
||
coord_cartesian(
|
||
ylim = c(NA, 15000),
|
||
clip = "off"
|
||
)
|
||
```
|
||
|
||
## Clipping
|
||
|
||
```{r}
|
||
#| label: coord-clip-text
|
||
#| output-location: column
|
||
#| code-line-numbers: "2,3|6,7,8,9,10|12"
|
||
ggplot(
|
||
filter(bikes, is_holiday == TRUE),
|
||
aes(x = temp_feel, y = count)
|
||
) +
|
||
geom_point() +
|
||
geom_text(
|
||
aes(label = season),
|
||
nudge_x = .3,
|
||
hjust = 0
|
||
) +
|
||
coord_cartesian(
|
||
clip = "off"
|
||
)
|
||
```
|
||
|
||
## ... or better use {ggrepel}
|
||
|
||
```{r}
|
||
#| label: coord-clip-text-repel
|
||
#| output-location: column
|
||
#| code-line-numbers: "6"
|
||
ggplot(
|
||
filter(bikes, is_holiday == TRUE),
|
||
aes(x = temp_feel, y = count)
|
||
) +
|
||
geom_point() +
|
||
ggrepel::geom_text_repel(
|
||
aes(label = season),
|
||
nudge_x = .3,
|
||
hjust = 0
|
||
) +
|
||
coord_cartesian(
|
||
clip = "off"
|
||
)
|
||
```
|
||
|
||
## Remove All Padding
|
||
|
||
```{r}
|
||
#| label: coord-expand-off-clip
|
||
#| output-location: column
|
||
#| code-line-numbers: "7|8"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = count)
|
||
) +
|
||
geom_point() +
|
||
coord_cartesian(
|
||
expand = FALSE,
|
||
clip = "off"
|
||
)
|
||
```
|
||
|
||
## Fixed Coordinate System
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: coord-fixed
|
||
#| fig-height: 4.2
|
||
#| code-line-numbers: "6"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = temp)
|
||
) +
|
||
geom_point() +
|
||
coord_fixed()
|
||
```
|
||
|
||
::: fragment
|
||
```{r}
|
||
#| label: coord-fixed-custom
|
||
#| fig-height: 4.2
|
||
#| code-line-numbers: "6"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp_feel, y = temp)
|
||
) +
|
||
geom_point() +
|
||
coord_fixed(ratio = 4)
|
||
```
|
||
:::
|
||
:::
|
||
|
||
## Flipped Coordinate System
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: coord-cartesian-comp-flip
|
||
#| fig-height: 4.1
|
||
#| code-line-numbers: "6"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = weather_type)
|
||
) +
|
||
geom_bar() +
|
||
coord_cartesian()
|
||
```
|
||
|
||
```{r}
|
||
#| label: coord-flip
|
||
#| fig-height: 4.1
|
||
#| code-line-numbers: "6"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = weather_type)
|
||
) +
|
||
geom_bar() +
|
||
coord_flip()
|
||
```
|
||
:::
|
||
|
||
## Flipped Coordinate System
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: coord-cartesian-switch-x-y
|
||
#| fig-height: 4.1
|
||
#| code-line-numbers: "3,6"
|
||
ggplot(
|
||
bikes,
|
||
aes(y = weather_type)
|
||
) +
|
||
geom_bar() +
|
||
coord_cartesian()
|
||
```
|
||
|
||
```{r}
|
||
#| label: coord-flip-again
|
||
#| fig-height: 4.1
|
||
#| code-line-numbers: "3,6"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = weather_type)
|
||
) +
|
||
geom_bar() +
|
||
coord_flip()
|
||
```
|
||
:::
|
||
|
||
## Reminder: Sort Your Bars!
|
||
|
||
```{r}
|
||
#| label: forcats-sort-infreq
|
||
#| output-location: column
|
||
#| code-line-numbers: "3|2"
|
||
ggplot(
|
||
filter(bikes, !is.na(weather_type)),
|
||
aes(y = fct_infreq(weather_type))
|
||
) +
|
||
geom_bar()
|
||
```
|
||
|
||
## Reminder: Sort Your Bars!
|
||
|
||
```{r}
|
||
#| label: forcats-sort-infreq-rev
|
||
#| output-location: column
|
||
#| code-line-numbers: "3,4,5"
|
||
ggplot(
|
||
filter(bikes, !is.na(weather_type)),
|
||
aes(y = fct_rev(
|
||
fct_infreq(weather_type)
|
||
))
|
||
) +
|
||
geom_bar()
|
||
```
|
||
|
||
## Circular Corrdinate System
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: coord-polar
|
||
#| fig-height: 3.9
|
||
#| code-line-numbers: "7"
|
||
ggplot(
|
||
filter(bikes, !is.na(weather_type)),
|
||
aes(x = weather_type,
|
||
fill = weather_type)
|
||
) +
|
||
geom_bar() +
|
||
coord_polar()
|
||
```
|
||
|
||
::: fragment
|
||
```{r}
|
||
#| label: coord-cartesian-comp-polar
|
||
#| fig-height: 3.9
|
||
#| code-line-numbers: "7"
|
||
ggplot(
|
||
filter(bikes, !is.na(weather_type)),
|
||
aes(x = weather_type,
|
||
fill = weather_type)
|
||
) +
|
||
geom_bar() +
|
||
coord_cartesian()
|
||
```
|
||
:::
|
||
:::
|
||
|
||
## Circular Cordinate System
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: coord-polar-coxcomb
|
||
#| fig-height: 3.9
|
||
#| code-line-numbers: "6,7"
|
||
ggplot(
|
||
filter(bikes, !is.na(weather_type)),
|
||
aes(x = fct_infreq(weather_type),
|
||
fill = weather_type)
|
||
) +
|
||
geom_bar(width = 1) +
|
||
coord_polar()
|
||
```
|
||
|
||
```{r}
|
||
#| label: coord-cartesian-comp-polar-no-padding
|
||
#| fig-height: 3.9
|
||
#| code-line-numbers: "6,7"
|
||
ggplot(
|
||
filter(bikes, !is.na(weather_type)),
|
||
aes(x = fct_infreq(weather_type),
|
||
fill = weather_type)
|
||
) +
|
||
geom_bar(width = 1) +
|
||
coord_cartesian()
|
||
```
|
||
:::
|
||
|
||
## Circular Corrdinate System
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: coord-polar-theta-x
|
||
#| fig-height: 3.9
|
||
#| code-line-numbers: "7"
|
||
ggplot(
|
||
filter(bikes, !is.na(weather_type)),
|
||
aes(x = fct_infreq(weather_type),
|
||
fill = weather_type)
|
||
) +
|
||
geom_bar() +
|
||
coord_polar(theta = "x")
|
||
```
|
||
|
||
```{r}
|
||
#| label: coord-polar-theta-y
|
||
#| fig-height: 3.9
|
||
#| code-line-numbers: "7"
|
||
ggplot(
|
||
filter(bikes, !is.na(weather_type)),
|
||
aes(x = fct_infreq(weather_type),
|
||
fill = weather_type)
|
||
) +
|
||
geom_bar() +
|
||
coord_polar(theta = "y")
|
||
```
|
||
:::
|
||
|
||
## Circular Corrdinate System
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: coord-polar-pie
|
||
#| fig-height: 4.1
|
||
#| code-line-numbers: "5"
|
||
ggplot(
|
||
filter(bikes, !is.na(weather_type)),
|
||
aes(x = 1, fill = weather_type)
|
||
) +
|
||
geom_bar(position = "stack") +
|
||
coord_polar(theta = "y")
|
||
```
|
||
|
||
```{r}
|
||
#| label: coord-cartesian-comp-polar-stacked
|
||
#| fig-height: 4.1
|
||
#| code-line-numbers: "5"
|
||
ggplot(
|
||
filter(bikes, !is.na(weather_type)),
|
||
aes(x = 1, fill = weather_type)
|
||
) +
|
||
geom_bar(position = "stack") +
|
||
coord_cartesian()
|
||
```
|
||
:::
|
||
|
||
## Circular Corrdinate System
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: coord-polar-pie-sorted
|
||
#| fig-height: 3.6
|
||
#| code-line-numbers: "4,6,7"
|
||
ggplot(
|
||
filter(bikes, !is.na(weather_type)),
|
||
aes(x = 1,
|
||
fill = fct_rev(fct_infreq(weather_type)))
|
||
) +
|
||
geom_bar(position = "stack") +
|
||
coord_polar(theta = "y") +
|
||
scale_fill_discrete(name = NULL)
|
||
```
|
||
|
||
```{r}
|
||
#| label: coord-cartesian-comp-polar-stacked-sorted
|
||
#| fig-height: 3.6
|
||
#| code-line-numbers: "4,6,7"
|
||
ggplot(
|
||
filter(bikes, !is.na(weather_type)),
|
||
aes(x = 1,
|
||
fill = fct_rev(fct_infreq(weather_type)))
|
||
) +
|
||
geom_bar(position = "stack") +
|
||
coord_cartesian() +
|
||
scale_fill_discrete(name = NULL)
|
||
```
|
||
:::
|
||
|
||
## Transform a Coordinate System
|
||
|
||
```{r}
|
||
#| label: coord-trans-log
|
||
#| output-location: column
|
||
#| code-line-numbers: "6"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp, y = count)
|
||
) +
|
||
geom_point() +
|
||
coord_trans(y = "log10")
|
||
```
|
||
|
||
## Transform a Coordinate System
|
||
|
||
::: {layout-ncol="2"}
|
||
```{r}
|
||
#| label: trans-log-via-coord
|
||
#| fig-height: 3.6
|
||
#| code-line-numbers: "6"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp, y = count,
|
||
group = day_night)
|
||
) +
|
||
geom_point() +
|
||
geom_smooth(method = "lm") +
|
||
coord_trans(y = "log10")
|
||
```
|
||
|
||
::: fragment
|
||
```{r}
|
||
#| label: trans-log-via-scale
|
||
#| fig-height: 3.6
|
||
#| code-line-numbers: "6"
|
||
ggplot(
|
||
bikes,
|
||
aes(x = temp, y = count,
|
||
group = day_night)
|
||
) +
|
||
geom_point() +
|
||
geom_smooth(method = "lm") +
|
||
scale_y_log10()
|
||
```
|
||
:::
|
||
:::
|
||
|
||
|
||
# 图形组合
|
||
|
||
------------------------------------------------------------------------
|
||
|
||
![Illustration by [Allison Horst](https://github.com/allisonhorst/stats-illustrations)](../../img/layout/ah_patchwork.jpg){fig-align="center" fig-alt="Allison Horsts monster illustration of the patchwork extension package."}
|
||
|
||
::: footer
|
||
:::
|
||
|
||
------------------------------------------------------------------------
|
||
|
||
::: panel-tabset
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| label: patchwork-p1
|
||
#| fig-width: 10
|
||
#| fig-height: 5.8
|
||
#| echo: false
|
||
theme_std <- theme_set(theme_minimal(base_size = 18))
|
||
theme_update(
|
||
# text = element_text(family = "Pally"),
|
||
panel.grid = element_blank(),
|
||
axis.text = element_text(color = "grey50", size = 12),
|
||
axis.title = element_text(color = "grey40", face = "bold"),
|
||
axis.title.x = element_text(margin = margin(t = 12)),
|
||
axis.title.y = element_text(margin = margin(r = 12)),
|
||
axis.line = element_line(color = "grey80", size = .4),
|
||
legend.text = element_text(color = "grey50", size = 12),
|
||
plot.tag = element_text(size = 40, margin = margin(b = 15)),
|
||
plot.background = element_rect(fill = "white", color = "white")
|
||
)
|
||
|
||
bikes_sorted <-
|
||
bikes %>%
|
||
filter(!is.na(weather_type)) %>%
|
||
group_by(weather_type) %>%
|
||
mutate(sum = sum(count)) %>%
|
||
ungroup() %>%
|
||
mutate(
|
||
weather_type = forcats::fct_reorder(
|
||
str_to_title(str_wrap(weather_type, 5)), sum
|
||
)
|
||
)
|
||
|
||
p1 <- ggplot(
|
||
bikes_sorted,
|
||
aes(x = weather_type, y = count, color = weather_type)
|
||
) +
|
||
geom_hline(yintercept = 0, color = "grey80", size = .4) +
|
||
stat_summary(
|
||
geom = "point", fun = "sum", size = 12
|
||
) +
|
||
stat_summary(
|
||
geom = "linerange", ymin = 0, fun.max = function(y) sum(y),
|
||
size = 2, show.legend = FALSE
|
||
) +
|
||
coord_flip(ylim = c(0, NA), clip = "off") +
|
||
scale_y_continuous(
|
||
expand = c(0, 0), limits = c(0, 8500000),
|
||
labels = scales::comma_format(scale = .0001, suffix = "K")
|
||
) +
|
||
scale_color_viridis_d(
|
||
option = "magma", direction = -1, begin = .1, end = .9, name = NULL,
|
||
guide = guide_legend(override.aes = list(size = 7))
|
||
) +
|
||
labs(
|
||
x = NULL, y = "Sum of reported bike shares", tag = "P1",
|
||
) +
|
||
theme(
|
||
axis.line.y = element_blank(),
|
||
axis.text.y = element_text(family = "Pally", color = "grey50", face = "bold",
|
||
margin = margin(r = 15), lineheight = .9)
|
||
)
|
||
|
||
p1
|
||
```
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| label: patchwork-p1
|
||
#| eval: false
|
||
```
|
||
:::
|
||
|
||
------------------------------------------------------------------------
|
||
|
||
::: panel-tabset
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| label: patchwork-p2
|
||
#| fig-width: 10
|
||
#| fig-height: 5.8
|
||
#| echo: false
|
||
p2 <- bikes_sorted %>%
|
||
filter(season == "winter", is_weekend == TRUE, day_night == "night") %>%
|
||
group_by(weather_type, .drop = FALSE) %>%
|
||
mutate(id = row_number()) %>%
|
||
ggplot(
|
||
aes(x = weather_type, y = id, color = weather_type)
|
||
) +
|
||
geom_point(size = 4.5) +
|
||
scale_color_viridis_d(
|
||
option = "magma", direction = -1, begin = .1, end = .9, name = NULL,
|
||
guide = guide_legend(override.aes = list(size = 7))
|
||
) +
|
||
labs(
|
||
x = NULL, y = "Reported bike shares on\nweekend winter nights", tag = "P2",
|
||
) +
|
||
coord_cartesian(ylim = c(.5, NA), clip = "off")
|
||
|
||
p2
|
||
```
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| label: patchwork-p2
|
||
#| eval: false
|
||
```
|
||
:::
|
||
|
||
------------------------------------------------------------------------
|
||
|
||
::: panel-tabset
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| label: patchwork-p3
|
||
#| fig-width: 10
|
||
#| fig-height: 5.8
|
||
#| echo: false
|
||
my_colors <- c("#cc0000", "#000080")
|
||
|
||
p3 <- bikes %>%
|
||
group_by(week = lubridate::week(date), day_night, year) %>%
|
||
summarize(count = sum(count)) %>%
|
||
group_by(week, day_night) %>%
|
||
mutate(avg = mean(count)) %>%
|
||
ggplot(aes(x = week, y = count, group = interaction(day_night, year))) +
|
||
geom_line(color = "grey65", size = 1) +
|
||
geom_line(aes(y = avg, color = day_night), stat = "unique", size = 1.7) +
|
||
annotate(
|
||
geom = "text", label = c("Day", "Night"), color = my_colors,
|
||
x = c(5, 18), y = c(125000, 29000), size = 8, fontface = "bold", family = "Pally"
|
||
) +
|
||
scale_x_continuous(breaks = c(1, 1:10*5)) +
|
||
scale_y_continuous(labels = scales::comma_format()) +
|
||
scale_color_manual(values = my_colors, guide = "none") +
|
||
labs(
|
||
x = "Week of the Year", y = "Reported bike shares\n(cumulative # per week)", tag = "P3",
|
||
)
|
||
|
||
p3
|
||
```
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| label: patchwork-p3
|
||
#| eval: false
|
||
```
|
||
:::
|
||
|
||
## {patchwork}
|
||
|
||
```{r}
|
||
#| label: patchwork-composition
|
||
#| fig-width: 15
|
||
#| fig-height: 12
|
||
#| fig-align: "center"
|
||
#| code-line-numbers: "3|2,3"
|
||
# install.packages("patchwork")
|
||
require(patchwork)
|
||
(p1 + p2) / p3
|
||
```
|
||
|
||
## "Collect Guides"
|
||
|
||
```{r}
|
||
#| label: patchwork-composition-guides
|
||
#| fig-width: 15
|
||
#| fig-height: 12
|
||
#| fig-align: "center"
|
||
(p1 + p2) / p3 + plot_layout(guides = "collect")
|
||
```
|
||
|
||
## Apply Theming
|
||
|
||
```{r}
|
||
#| label: patchwork-composition-guides-just
|
||
#| fig-width: 15
|
||
#| fig-height: 12
|
||
#| fig-align: "center"
|
||
((p1 + p2) / p3 & theme(legend.justification = "top")) +
|
||
plot_layout(guides = "collect")
|
||
```
|
||
|
||
## Apply Theming
|
||
|
||
```{r}
|
||
#| label: patchwork-composition-legend-off
|
||
#| fig-width: 15
|
||
#| fig-height: 12
|
||
#| fig-align: "center"
|
||
(p1 + p2) / p3 & theme(legend.position = "none",
|
||
plot.background = element_rect(color = "black", size = 3))
|
||
```
|
||
|
||
## Adjust Widths and Heights
|
||
|
||
```{r}
|
||
#| label: patchwork-composition-heights-widths
|
||
#| fig-width: 15
|
||
#| fig-height: 12
|
||
#| fig-align: "center"
|
||
#| code-line-numbers: "2"
|
||
((p1 + p2) / p3 & theme(legend.position = "none")) +
|
||
plot_layout(heights = c(.2, .1), widths = c(2, 1))
|
||
```
|
||
|
||
## Use A Custom Layout
|
||
|
||
```{r}
|
||
#| label: patchwork-composition-design
|
||
#| fig-width: 15
|
||
#| fig-height: 12
|
||
#| fig-align: "center"
|
||
#| code-line-numbers: "1,2,3,4|5"
|
||
picasso <- "
|
||
AAAAAA#BBBB
|
||
CCCCCCCCC##
|
||
CCCCCCCCC##"
|
||
(p1 + p2 + p3 & theme(legend.position = "none")) +
|
||
plot_layout(design = picasso)
|
||
```
|
||
|
||
## Add Labels
|
||
|
||
```{r}
|
||
#| label: patchwork-composition-labs-prep
|
||
pl1 <- p1 + labs(tag = NULL, title = "Plot One") + theme(legend.position = "none")
|
||
pl2 <- p2 + labs(tag = NULL, title = "Plot Two") + theme(legend.position = "none")
|
||
pl3 <- p3 + labs(tag = NULL, title = "Plot Three") + theme(legend.position = "none")
|
||
```
|
||
|
||
## Add Labels
|
||
|
||
```{r}
|
||
#| label: patchwork-composition-labs
|
||
#| fig-width: 15
|
||
#| fig-height: 12
|
||
#| fig-align: "center"
|
||
#| code-line-numbers: "2"
|
||
(pl1 + pl2) / pl3 +
|
||
plot_annotation(tag_levels = "1",
|
||
tag_prefix = "P",
|
||
title = "An overarching title for all 3 plots, placed on the very top while all other titles are sitting below the tags.")
|
||
```
|
||
|
||
## Add Text
|
||
|
||
::: panel-tabset
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| label: patchwork-composition-textbox-prep
|
||
#| echo: false
|
||
#| fig-width: 9
|
||
#| fig-height: 4.5
|
||
#| fig-align: "center"
|
||
text <- tibble::tibble(
|
||
x = 0, y = 0, label = "Lorem ipsum dolor sit amet, **consectetur adipiscing elit**, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation <b style='color:#000080;'>ullamco laboris nisi</b> ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat <b style='color:#cc0000;'>cupidatat non proident</b>, sunt in culpa qui officia deserunt mollit anim id est laborum."
|
||
)
|
||
pt <- ggplot(text, aes(x = x, y = y)) +
|
||
ggtext::geom_textbox(
|
||
aes(label = label),
|
||
box.color = NA, width = unit(23, "lines"),
|
||
color = "grey40", size = 6.5, lineheight = 1.4
|
||
) +
|
||
coord_cartesian(expand = FALSE, clip = "off") +
|
||
theme_void()
|
||
pt
|
||
```
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| label: patchwork-composition-textbox-prep
|
||
#| eval: false
|
||
```
|
||
:::
|
||
|
||
## Add Text
|
||
|
||
```{r}
|
||
#| label: patchwork-composition-textbox
|
||
#| fig-width: 15
|
||
#| fig-height: 12
|
||
#| fig-align: "center"
|
||
(p1 + pt) / p3
|
||
```
|
||
|
||
## Add Inset Plots
|
||
|
||
```{r}
|
||
#| label: patchwork-composition-inset-1
|
||
#| fig-width: 12
|
||
#| fig-height: 7
|
||
#| fig-align: "center"
|
||
pl1 + inset_element(pl2,
|
||
l = .6, b = .1, r = 1, t = .6)
|
||
```
|
||
|
||
## Add Inset Plots
|
||
|
||
```{r}
|
||
#| label: patchwork-composition-inset-2
|
||
#| fig-width: 12
|
||
#| fig-height: 7
|
||
#| fig-align: "center"
|
||
pl1 + inset_element(pl2,
|
||
l = .6, b = 0, r = 1, t = .5, align_to = 'full')
|
||
```
|
||
|
||
## Add Inset Plots
|
||
|
||
```{r}
|
||
#| label: patchwork-composition-inset-3
|
||
#| fig-width: 15
|
||
#| fig-height: 12
|
||
#| fig-align: "center"
|
||
(pl1 + inset_element(pl2,
|
||
l = .6, b = .1, r = 1, t = .6) + pt) / pl3
|
||
```
|
||
|
||
|
||
## 练习
|
||
|
||
```{r}
|
||
library(palmerpenguins)
|
||
library(ggthemes)
|
||
penguins
|
||
```
|
||
|
||
## 效果
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| warning: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
penguins |>
|
||
ggplot(aes(x = flipper_length_mm, y = body_mass_g)) +
|
||
geom_point(aes(color = species, shape = species)) +
|
||
geom_smooth(method = "lm") +
|
||
labs(
|
||
title = "Body mass and flipper length",
|
||
subtitle = "Dimensions for Adelie, Chinstrap, and Gentoo Penguins",
|
||
x = "Flipper length (mm)",
|
||
y = "Body mass (g)",
|
||
color = "Species",
|
||
shape = "Species"
|
||
) +
|
||
scale_color_colorblind()
|
||
```
|
||
|
||
|
||
```{r}
|
||
#| include: false
|
||
#| fig-alt: |
|
||
#| A blank, gray plot area.
|
||
|
||
ggplot(data = penguins)
|
||
```
|
||
|
||
|
||
```{r}
|
||
#| include: false
|
||
ggplot(
|
||
data = penguins,
|
||
mapping = aes(x = flipper_length_mm, y = body_mass_g)
|
||
)
|
||
```
|
||
|
||
|
||
```{r}
|
||
#| include: false
|
||
#| fig-alt: |
|
||
#| A scatterplot of body mass vs. flipper length of penguins. The plot
|
||
#| displays a positive, linear, and relatively strong relationship between
|
||
#| these two variables.
|
||
|
||
ggplot(
|
||
data = penguins,
|
||
mapping = aes(x = flipper_length_mm, y = body_mass_g)
|
||
) +
|
||
geom_point()
|
||
```
|
||
|
||
|
||
```{r}
|
||
#| include: false
|
||
#| warning: false
|
||
#| fig-alt: |
|
||
#| A scatterplot of body mass vs. flipper length of penguins. The plot
|
||
#| displays a positive, fairly linear, and relatively strong relationship
|
||
#| between these two variables. Species (Adelie, Chinstrap, and Gentoo)
|
||
#| are represented with different colors.
|
||
|
||
ggplot(
|
||
data = penguins,
|
||
mapping = aes(x = flipper_length_mm, y = body_mass_g, color = species)
|
||
) +
|
||
geom_point()
|
||
```
|
||
|
||
|
||
```{r}
|
||
#| include: false
|
||
#| warning: false
|
||
#| fig-alt: |
|
||
#| A scatterplot of body mass vs. flipper length of penguins. Overlaid
|
||
#| on the scatterplot are three smooth curves displaying the
|
||
#| relationship between these variables for each species (Adelie,
|
||
#| Chinstrap, and Gentoo). Different penguin species are plotted in
|
||
#| different colors for the points and the smooth curves.
|
||
|
||
ggplot(
|
||
data = penguins,
|
||
mapping = aes(x = flipper_length_mm, y = body_mass_g, color = species)
|
||
) +
|
||
geom_point() +
|
||
geom_smooth(method = "lm")
|
||
```
|
||
|
||
|
||
```{r}
|
||
#| include: false
|
||
#| warning: false
|
||
#| fig-alt: |
|
||
#| A scatterplot of body mass vs. flipper length of penguins. Overlaid
|
||
#| on the scatterplot is a single line of best fit displaying the
|
||
#| relationship between these variables for each species (Adelie,
|
||
#| Chinstrap, and Gentoo). Different penguin species are plotted in
|
||
#| different colors for the points only.
|
||
|
||
ggplot(
|
||
data = penguins,
|
||
mapping = aes(x = flipper_length_mm, y = body_mass_g)
|
||
) +
|
||
geom_point(mapping = aes(color = species)) +
|
||
geom_smooth(method = "lm")
|
||
```
|
||
|
||
|
||
```{r}
|
||
#| include: false
|
||
#| warning: false
|
||
#| fig-alt: |
|
||
#| A scatterplot of body mass vs. flipper length of penguins. Overlaid
|
||
#| on the scatterplot is a single line of best fit displaying the
|
||
#| relationship between these variables for each species (Adelie,
|
||
#| Chinstrap, and Gentoo). Different penguin species are plotted in
|
||
#| different colors and shapes for the points only.
|
||
|
||
ggplot(
|
||
data = penguins,
|
||
mapping = aes(x = flipper_length_mm, y = body_mass_g)
|
||
) +
|
||
geom_point(mapping = aes(color = species, shape = species)) +
|
||
geom_smooth(method = "lm")
|
||
```
|
||
|
||
## 练习
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
p <- ggplot(
|
||
data = penguins,
|
||
mapping = aes(x = flipper_length_mm, y = body_mass_g)
|
||
) +
|
||
geom_point(aes(color = species, shape = species)) +
|
||
geom_smooth(method = "lm") +
|
||
labs(
|
||
title = "Body mass and flipper length",
|
||
subtitle = "Dimensions for Adelie, Chinstrap, and Gentoo Penguins",
|
||
x = "Flipper length (mm)", y = "Body mass (g)",
|
||
color = "Species", shape = "Species"
|
||
) +
|
||
scale_color_colorblind()
|
||
```
|
||
|
||
|
||
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 练习
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
|
||
```{r}
|
||
#| warning: false
|
||
#| fig-alt: |
|
||
#| A scatterplot of body mass vs. flipper length of penguins, colored
|
||
#| by bill depth. A smooth curve of the relationship between body mass
|
||
#| and flipper length is overlaid. The relationship is positive,
|
||
#| fairly linear, and moderately strong.
|
||
p <- ggplot(
|
||
data = penguins,
|
||
mapping = aes(x = flipper_length_mm, y = body_mass_g)) +
|
||
geom_point(aes(color = bill_depth_mm)) +
|
||
geom_smooth()
|
||
```
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 练习
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
p <- ggplot(
|
||
data = penguins,
|
||
mapping = aes(x = flipper_length_mm, y = body_mass_g, color = island)
|
||
) +
|
||
geom_point() +
|
||
geom_smooth(se = FALSE)
|
||
```
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 分层展示
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
p <- ggplot(
|
||
data = penguins,
|
||
mapping = aes(x = flipper_length_mm, y = body_mass_g)
|
||
) +
|
||
geom_point() +
|
||
geom_smooth()
|
||
```
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 柱状图
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| fig-alt: |
|
||
#| A bar chart of frequencies of species of penguins: Adelie
|
||
#| (approximately 150), Chinstrap (approximately 90), Gentoo
|
||
#| (approximately 125).
|
||
|
||
p <- ggplot(penguins, aes(x = species)) +
|
||
geom_bar()
|
||
```
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 柱状图
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| fig-alt: |
|
||
#| A bar chart of frequencies of species of penguins, where the bars are
|
||
#| ordered in decreasing order of their heights (frequencies): Adelie
|
||
#| (approximately 150), Gentoo (approximately 125), Chinstrap
|
||
#| (approximately 90).
|
||
|
||
p <- ggplot(penguins, aes(x = fct_infreq(species))) +
|
||
geom_bar()
|
||
```
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
|
||
## 直方图
|
||
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| warning: false
|
||
#| fig-alt: |
|
||
#| A histogram of body masses of penguins. The distribution is unimodal
|
||
#| and right skewed, ranging between approximately 2500 to 6500 grams.
|
||
|
||
p <- ggplot(penguins, aes(x = body_mass_g)) +
|
||
geom_histogram(binwidth = 200)
|
||
```
|
||
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 直方图
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| warning: false
|
||
#| layout-ncol: 2
|
||
#| fig-width: 3
|
||
#| fig-alt: |
|
||
#| Two histograms of body masses of penguins, one with binwidth of 20
|
||
#| (left) and one with binwidth of 2000 (right). The histogram with binwidth
|
||
#| of 20 shows lots of ups and downs in the heights of the bins, creating a
|
||
#| jagged outline. The histogram with binwidth of 2000 shows only three bins.
|
||
|
||
p1 <- ggplot(penguins, aes(x = body_mass_g)) +
|
||
geom_histogram(binwidth = 20)
|
||
p2 <- ggplot(penguins, aes(x = body_mass_g)) +
|
||
geom_histogram(binwidth = 2000)
|
||
p <- p1 + p2
|
||
```
|
||
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 10
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 密度图
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| fig-alt: |
|
||
#| A density plot of body masses of penguins. The distribution is unimodal
|
||
#| and right skewed, ranging between approximately 2500 to 6500 grams.
|
||
|
||
p <- ggplot(penguins, aes(x = body_mass_g)) +
|
||
geom_density()
|
||
```
|
||
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
|
||
## 箱图
|
||
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
|
||
```{r}
|
||
#| warning: false
|
||
#| fig-alt: |
|
||
#| Side-by-side box plots of distributions of body masses of Adelie,
|
||
#| Chinstrap, and Gentoo penguins. The distribution of Adelie and
|
||
#| Chinstrap penguins' body masses appear to be symmetric with
|
||
#| medians around 3750 grams. The median body mass of Gentoo penguins
|
||
#| is much higher, around 5000 grams, and the distribution of the
|
||
#| body masses of these penguins appears to be somewhat right skewed.
|
||
|
||
p <- ggplot(penguins,
|
||
aes(x = species, y = body_mass_g)) +
|
||
geom_boxplot()
|
||
```
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 分组
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| warning: false
|
||
#| fig-alt: |
|
||
#| A density plot of body masses of penguins by species of penguins. Each
|
||
#| species (Adelie, Chinstrap, and Gentoo) is represented with different
|
||
#| colored outlines for the density curves.
|
||
|
||
p <- ggplot(penguins,
|
||
aes(x = body_mass_g, color = species)) +
|
||
geom_density(linewidth = 0.75)
|
||
```
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 分组
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| warning: false
|
||
#| fig-alt: |
|
||
#| A density plot of body masses of penguins by species of penguins. Each
|
||
#| species (Adelie, Chinstrap, and Gentoo) is represented in different
|
||
#| colored outlines for the density curves. The density curves are also
|
||
#| filled with the same colors, with some transparency added.
|
||
|
||
p <- ggplot(penguins,
|
||
aes(x = body_mass_g, color = species, fill = species)) +
|
||
geom_density(alpha = 0.5)
|
||
```
|
||
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
|
||
## 分组
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| fig-alt: |
|
||
#| Bar plots of penguin species by island (Biscoe, Dream, and Torgersen)
|
||
p <- ggplot(penguins,
|
||
aes(x = island, fill = species)) +
|
||
geom_bar()
|
||
```
|
||
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
|
||
## 分组
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| fig-alt: |
|
||
#| Bar plots of penguin species by island (Biscoe, Dream, and Torgersen)
|
||
#| the bars are scaled to the same height, making it a relative frequencies
|
||
#| plot
|
||
|
||
p <- ggplot(penguins,
|
||
aes(x = island, fill = species)) +
|
||
geom_bar(position = "fill")
|
||
```
|
||
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 分组
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| warning: false
|
||
#| fig-alt: |
|
||
#| A scatterplot of body mass vs. flipper length of penguins. The plot
|
||
#| displays a positive, linear, relatively strong relationship between
|
||
#| these two variables.
|
||
|
||
p <- ggplot(penguins,
|
||
aes(x = flipper_length_mm, y = body_mass_g)) +
|
||
geom_point()
|
||
```
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 分组
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| warning: false
|
||
#| fig-alt: |
|
||
#| A scatterplot of body mass vs. flipper length of penguins. The plot
|
||
#| displays a positive, linear, relatively strong relationship between
|
||
#| these two variables. The points are colored based on the species of the
|
||
#| penguins and the shapes of the points represent islands (round points are
|
||
#| Biscoe island, triangles are Dream island, and squared are Torgersen
|
||
#| island). The plot is very busy and it's difficult to distinguish the shapes
|
||
#| of the points.
|
||
|
||
p <- ggplot(penguins,
|
||
aes(x = flipper_length_mm, y = body_mass_g)) +
|
||
geom_point(aes(color = species, shape = island))
|
||
```
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
|
||
## 分面
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| warning: false
|
||
#| fig-width: 8
|
||
#| fig-asp: 0.33
|
||
#| fig-alt: |
|
||
#| A scatterplot of body mass vs. flipper length of penguins. The shapes and
|
||
#| colors of points represent species. Penguins from each island are on a
|
||
#| separate facet. Within each facet, the relationship between body mass and
|
||
#| flipper length is positive, linear, relatively strong.
|
||
|
||
p <- ggplot(penguins,
|
||
aes(x = flipper_length_mm, y = body_mass_g)) +
|
||
geom_point(aes(color = species, shape = species)) +
|
||
facet_wrap(~island)
|
||
```
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 分面
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| warning: false
|
||
|
||
p <- ggplot(
|
||
data = penguins,
|
||
mapping = aes(
|
||
x = bill_length_mm, y = bill_depth_mm,
|
||
color = species, shape = species
|
||
)
|
||
) +
|
||
geom_point() +
|
||
labs(color = "Species")
|
||
```
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 练习
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
#| layout-ncol: 2
|
||
|
||
p1 <- ggplot(penguins, aes(x = island, fill = species)) +
|
||
geom_bar(position = "fill")
|
||
p2 <- ggplot(penguins, aes(x = species, fill = island)) +
|
||
geom_bar(position = "fill")
|
||
p <- p1 + p2
|
||
```
|
||
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 10
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 练习
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
p <- ggplot(penguins,
|
||
aes(x = flipper_length_mm, y = body_mass_g)) +
|
||
geom_point()
|
||
```
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 练习
|
||
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
p <- ggplot(mpg, aes(x = class)) +
|
||
geom_bar()
|
||
```
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 练习
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
|
||
```{r}
|
||
p <- ggplot(mpg, aes(x = cty, y = hwy)) +
|
||
geom_point()
|
||
```
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 练习
|
||
|
||
:::: {.panel-tabset}
|
||
|
||
### Code
|
||
|
||
```{r}
|
||
p <- ggplot(data = mpg) +
|
||
geom_point(mapping = aes(x = displ, y = hwy))
|
||
```
|
||
|
||
### Graphic
|
||
|
||
```{r}
|
||
#| echo: false
|
||
#| fig-width: 8
|
||
#| fig-height: 5
|
||
p
|
||
```
|
||
|
||
::::
|
||
|
||
## 欢迎讨论!{.center}
|
||
|
||
|
||
`r rmdify::slideend(wechat = FALSE, type = "public", tel = FALSE, thislink = "https://drwater.rcees.ac.cn/course/public/RWEP/@PUB/SD/")`
|
||
|