R基本繪圖函式
ggplot繪圖函式
knitr::opts_chunk$set(echo = TRUE)
# 本章需要套件
library(tidyverse)
library(dataskills)
library(plotly) # 製造互動式統計圖
library(cowplot) # 製造組合式統計圖
set.seed(30250) # 設定隨機種子
data("pets")
glimpse(pets)
## Rows: 800
## Columns: 6
## $ id <chr> "S001", "S002", "S003", "S004", "S005", "S006", "S007", "S008"~
## $ pet <fct> dog, dog, dog, dog, dog, dog, dog, dog, dog, dog, dog, dog, do~
## $ country <fct> UK, UK, UK, UK, UK, UK, UK, UK, UK, UK, UK, UK, UK, UK, UK, UK~
## $ score <int> 90, 107, 94, 120, 111, 110, 100, 107, 106, 109, 85, 110, 102, ~
## $ age <int> 6, 8, 2, 10, 4, 8, 9, 8, 6, 11, 5, 9, 1, 10, 7, 8, 1, 8, 5, 13~
## $ weight <dbl> 19.78932, 20.01422, 19.14863, 19.56953, 21.39259, 21.31880, 19~
levels(pets$pet)
## [1] "dog" "cat" "ferret"
levels(pets$country)
## [1] "UK" "NL"
檢視pets的六個變項的資料型態,屬於那種變項尺度?(建議暫停影片)
連續變項 Continuous variables:“score”, “age”,“weight”
間斷/類別變項 Discrete (or categorical) variables: “pet”,“country”
R基本繪圖函式 plot()
思維:在即定框架內一體成形 用途:初窺資料模式;規劃分析策略
plot(x = pets$pet)
柱狀圖告訴我們的事:
plot(x = pets$pet, y = pets$score)
箱型圖告訴我們的事:
plot(x = pets$age, y = pets$weight)
散佈圖告訴我們的事:
hist(pets$score, breaks = 20)
直方圖告訴我們的事:
改變breaks的數值,觀察輸出直方圖的變化。
思維:繪圖如製作蛋糕,一層一層堆疊素材 用途:製作展示用的統計圖
ggplot()
mapping <- aes(x = pet,
y = score,
colour = country,
fill = country)
ggplot(data = pets, mapping = mapping)
ggplot(pets, aes(pet, score, colour = country, fill = country)) +
geom_violin(alpha = 0.5) +
labs(x = "Pet type",
y = "Score on an Important Test",
colour = "Country of Origin",
fill = "Country of Origin",
title = "My first plot!") +
theme_bw(base_size = 15)
建議測試: - 改變alpha
,base_size
的數值,觀察輸出效果 - 更改labs()
各參數的英文詞,觀察輸出效果
適用:類別變項資料計數。
對照基本繪圖:柱狀圖
ggplot(pets, aes(pet)) +
geom_bar()
適用:連續變項資料次數分佈,依類別變項分組呈現。
對照基本繪圖:箱型圖
ggplot(pets, aes(pet, score, fill=pet)) +
geom_boxplot(alpha = 1)
適用:呈現來自相同的觀察單位,兩種連續變項資料的次數分佈。
對照基本繪圖:散佈圖
ggplot(pets, aes(age, score, color = pet)) +
geom_point(alpha=0.5)
適用:呈現一種連續變項資料的次數分佈;可判別變異趨勢;樣本數越多越清楚。
對照基本繪圖:直方圖
ggplot(pets, aes(score)) +
geom_histogram(binwidth = 5, fill = "white", color = "black")
搭配參數fill
與position
,一張直方圖可呈現分組資料分佈。
ggplot(pets, aes(score, fill=pet)) +
geom_histogram(binwidth = 5, alpha = 0.5,
position = "dodge")
建議測試
將參數position
的值改成“identity”, “fill”, “dodge”, 或 “stack”,觀察輸出效果。
適用:呈現一種連續變項資料的次數分佈;可判別變異趨勢;樣本數上千越清楚。
ggplot(pets, aes(score)) +
geom_density()
搭配參數group
,fill
與color
,一張分佈密度圖可呈現分組資料分佈。
ggplot(pets, aes(score, fill = pet)) +
geom_density(alpha = 0.5)
Try changing the alpha
argument to figure out what it does.
建議測試
改變alpha
的數值,觀察輸出效果
適用:呈現一種連續變項資料的次數分佈;可判別變異趨勢;樣本數上千越清楚。
ggplot(pets, aes(score, color = pet)) +
geom_freqpoly(binwidth = 5)
Try changing the binwidth
argument to 5 and 0.1. How do you figure out the right value?
建議測試
改變binwidth
的數值,觀察輸出效果
小提琴圖是比箱型圖更直觀的資料次數分佈圖,非常態資料分佈一目了然。
ggplot(pets, aes(pet, score, fill=pet)) +
geom_violin(draw_quantiles = .5,
trim = FALSE, alpha = 0.5,)
建議測試
改變draw_quantile
的數值,從0.1到0.9皆可,觀察輸出效果
適用:使用函式stat_summary
, geom_bar
, geom_col
, geom_col
,將分組統計值轉化為柱狀圖的元素。
ggplot(pets, aes(pet, score, fill=pet)) +
stat_summary(fun = mean, geom = "col", alpha = 0.5) +
stat_summary(fun.data = mean_se, geom = "errorbar",
width = 0.25) +
coord_cartesian(ylim = c(80, 120))
建議測試
改變coord_cartesian
的數值,觀察輸出效果
分組描述統計的重要資訊是集中量數(平均值)與誤差範圍(標準差、信賴區間)。以下分組箱形圖的箱子高度,代表距離平均值一個標準差的數值。
ggplot(pets, aes(pet, score, color=pet)) +
stat_summary(fun.data = mean_se, geom = "crossbar") +
stat_summary(fun.min = function(x) mean(x) - sd(x),
fun.max = function(x) mean(x) + sd(x),
geom = "errorbar", width = 0) +
theme(legend.position = "none") # gets rid of the legend
以下R程式碼計算分組平均值與標準誤(standard error)。
pets_sum <- pets %>%
group_by(pet) %>%
summarize(mean = mean(score), se = sd(score)/sqrt(n()))
petsgg <- ggplot(pets_sum, aes(pet, mean,
ymin = mean-se,
ymax = mean+se))
以箱形呈現標準誤區間
petsgg + geom_crossbar()
以誤差線呈現標準誤區間
petsgg + geom_errorbar()
以直線呈現標準誤區間
petsgg + geom_linerange()
以點線呈現標準誤區間
petsgg + geom_pointrange()
散佈圖包含不只一組資料時,加上迴歸線能呈現分組的資料分佈趨勢。
ggplot(pets, aes(age, score, color = pet)) +
geom_smooth(formula = y ~ x, method="lm")
建議測試
查詢geom_smooth
有關method
的說明,了解還有那些選項,觀察各種選項的輸出效果
ggplot的自訂函式,能改變統計圖的標籤文字、配色、以及畫布主題。
方法一:使用labs()
一次設定所有標籤
ggplot(x_vs_y, aes(x, y)) + geom_smooth(method=“lm”) + labs(title = “My Plot Title”, x = “The X Variable”, y = “The Y Variable”)
ggplot(pets, aes(age, score, color = pet)) +
geom_smooth(formula = y ~ x, method="lm") +
labs(title = "Pet score with Age",
x = "Age (in Years)",
y = "score Score",
color = "Pet Type")
方法二:使用ggtitle
,xlab()
,ylab()
設定各部位標籤
ggplot(x_vs_y, aes(x, y)) + geom_smooth(method=“lm”) + ggtitle(“My Plot Title”) + xlab(“The X Variable”) + ylab(“The Y Variable”)
ggplot(pets, aes(age, score, color = pet)) +
geom_smooth(formula = y ~ x, method="lm") +
ggtitle("Pet score with Age") +
xlab("Age (in Years)") +
ylab("score Score") +
scale_color_discrete(name = "Pet Type")
ggplot提供scale_colour_manual()
,scale_fill_manual()
等函式設定線條或區塊的配色,配色選項可參考Colours chapter in Cookbook for R。建議更改下圖的配色數值,觀察輸出效果。
ggplot(pets, aes(pet, score, colour = pet, fill = pet)) +
geom_violin() +
scale_color_manual(values = c("darkgreen", "dodgerblue", "orange")) +
scale_fill_manual(values = c("#CCFFCC", "#BBDDFF", "#FFCC66"))
下圖是使用ggplot內建的主題minimal
呈現的效果。
ggplot(pets, aes(age, score, color = pet)) +
geom_smooth(formula = y ~ x, method="lm") +
theme_minimal(base_size = 18)
如果有特殊需求,使用者可以自建主題,以下是Lisa DeBrunie提供的vampire theme。如果你想建立個人風格的主題,可以嘗試更改各部份配色與字型大小,建立符合你的統計圖主題。
vampire_theme <- theme(
rect = element_rect(fill = "black"),
panel.background = element_rect(fill = "black"),
text = element_text(size = 20, colour = "white"),
axis.text = element_text(size = 16, colour = "grey70"),
line = element_line(colour = "white", size = 2),
panel.grid = element_blank(),
axis.line = element_line(colour = "white"),
axis.ticks = element_blank(),
legend.position = "top"
)
theme_set(vampire_theme)
ggplot(pets, aes(age, score, color = pet)) +
geom_smooth(formula = y ~ x, method="lm")
有需要匯出製作好的統計圖,將ggplot存入物件,使用ggsave()
使定匯出檔案名稱即可。如果你要指定輸出圖像的寛度與高度,ggsave()
可設定統計圖的width
與 height
,單位有“in”, “cm”, “mm”。
box <- ggplot(pets, aes(pet, score, fill=pet)) +
geom_boxplot(alpha = 0.5)
violin <- ggplot(pets, aes(pet, score, fill=pet)) +
geom_violin(alpha = 0.5)
ggsave("demog_violin_plot.png", width = 5, height = 7)
ggsave("demog_box_plot.jpg", plot = box, width = 5, height = 7)
The file type is set from the filename suffix, or by specifying the argument device
, which can take the following values: “eps”, “ps”, “tex”, “pdf”, “jpeg”, “tiff”, “png”, “bmp”, “svg” or “wmf”.
箱形圖能用來標記中位數與四分位區間。
ggplot(pets, aes(pet, score, fill = pet)) +
geom_violin(show.legend = FALSE) +
geom_boxplot(width = 0.2, fill = "white",
show.legend = FALSE) ## 通常不需顯示標籤
stat_summary()
內置的函式將在第七單元學習。
ggplot(pets, aes(pet, score, fill=pet)) +
geom_violin(trim = FALSE, alpha = 0.5) +
stat_summary(
fun = mean,
fun.max = function(x) {mean(x) + sd(x)},
fun.min = function(x) {mean(x) - sd(x)},
geom="pointrange"
)
當樣本資料數目不多, geom_jitter
可用資料點顯示資料分佈。
# sample_n chooses 50 random observations from the dataset
ggplot(sample_n(pets, 50), aes(pet, score, fill=pet)) +
geom_violin(
trim = FALSE,
draw_quantiles = c(0.25, 0.5, 0.75),
alpha = 0.5
) +
geom_jitter(
width = 0.15, # points spread out over 15% of available width
height = 0, # do not move position on the y-axis
alpha = 0.5,
size = 3
)
當分資料分組不多,如五組之內,在散佈圖內繪製迴歸線有助了解資料分佈。
ggplot(sample_n(pets, 50), aes(age, weight, colour = pet)) +
geom_point() +
geom_smooth(formula = y ~ x, method="lm")
資料點太多時,使用alpha
調整散佈圖資料點的透明度,運用colour
區分組別。
ggplot(pets, aes(age, score, colour = pet)) +
geom_point(alpha = 0.25) +
geom_smooth(formula = y ~ x, method="lm")
資料點太多時,使用geom_count()
調整散佈圖資料點的面積,表現各資料點的累積次數。
ggplot(pets, aes(age, score, colour = pet)) +
geom_count()
另一種方法是使用色彩突顯每個資料點的累積次數。scale_color_viridis_c()
是viridis package套件的函式,可讓連續變項的數值,轉換為對應的色彩。
pets %>%
group_by(age, score) %>%
summarise(count = n(), .groups = "drop") %>%
ggplot(aes(age, score, color=count)) +
geom_point(size = 2) +
scale_color_viridis_c()
當統計圖只呈現兩種連續變項,過多資料點無法看出重要資訊。
ggplot(pets, aes(age, score)) +
geom_point()
運用 geom_density2d()
就能產生像等高線的空照密度圖。
ggplot(pets, aes(age, score)) +
geom_density2d()
使用 stat_density_2d(aes(fill = ..level..), geom = "polygon")
可加上配色,強調次數密度差異。
ggplot(pets, aes(age, score)) +
stat_density_2d(aes(fill = ..level..), geom = "polygon") +
scale_fill_viridis_c()
使用 geom_bin2d()
可繪製像素化的密度圖。設定 binwidth
決定每塊像素的範圍。
ggplot(pets, aes(age, score)) +
geom_bin2d(binwidth = c(1, 5))
使用 geomhex()
可繪製蜂巢化的密度圖。 調整 binwidth
, xlim()
, ylim()
可決定蜂巢的格局
ggplot(pets, aes(age, score)) +
geom_hex(binwidth = c(1, 5))
相關熱點圖用在呈現兩種類別變項分佈的相關係。繪製熱點圖首先要轉換資料,以下用到的 gather()
將在第四及第五單元學習。
heatmap <- pets %>%
select_if(is.numeric) %>% # get just the numeric columns
cor() %>% # create the correlation matrix
as_tibble(rownames = "V1") %>% # make it a tibble
gather("V2", "r", 2:ncol(.)) # wide to long (V2)
轉換後的資料就能運用ggplot
繪製基本統計圖,再使用geom_tile()
轉換為統計圖。
ggplot(heatmap, aes(V1, V2, fill=r)) +
geom_tile() +
scale_fill_viridis_c()
plotly
套件用來產生互動式統計圖。 運用 ggplotly()
讓ggplot物件動起來。
demog_plot <- ggplot(pets, aes(age, score, fill=pet)) +
geom_point() +
geom_smooth(formula = y~x, method = lm)
ggplotly(demog_plot)