第 8 章 Facet 切圖

依照data frame中某些欄位將資料切成很多小的data frame, 一一套上相同的ggplot設計切割出很多小張但有相同幾何美學設計的圖群。

xfun::download_file("https://www.dropbox.com/s/v8rchkn63fzgjj3/drake_facet.Rdata?dl=1")
load("drake_facet.Rdata")

8.1 Facet wrap (單切面圖)

目標 不同行政區,三黨得票率
  • 面向欄位:原始資料要存在一個能區分不同行政區的欄位變數(假設叫地區)。

  • 基本圖設計:先畫好單一行政區「data frame」下,三黨得票率的直方圖(基本設計): ggplot_object

  • facet_wrap: 使用facet,自動將相同基本設計套用在不同行政區資料進行繪圖。

ggplot Object +
  facet_wrap(...)
facet_wrap in 3 steps

8.2 2020總統大選全國資料

  • 資料來源:
library(ggplot2)
library(dplyr)

dataSource <- "https://db.cec.gov.tw/histQuery.jsp?voteCode=20200101P1A1&qryType=ctks"
predElection2020 <- readxl::read_excel("~/Dropbox/github-data/109-1-econDV/election2020.xls")

8.2.1 Pseudo-codes

# 資料整理
df_byCounty <- {
  
  
}
# 基本設計
ggByCounty <- function(Xdata){
  ggplot(
    data=Xdata
  ) +
  geom_col(
    aes(
      x=號次, y=得票率, fill=號次
    )
  )
}
df_byCounty %>%
  filter(地區=="新北市") %>%
  ggByCounty()
# 切圖
ggfacet_election <- {
  df_byCounty %>%
  ggfacet_election() +
  facet_wrap(
    vars(地區)
  )
}

8.2.2 資料整理

predElection2020rev = {
  predElection2020 %>%
    filter(
      !is.na(號次)
    ) -> predElection2020_b
  predElection2020_b$地區 %>%
    na.omit() %>%
    purrr::map(
      ~{rep(.x,3)}
    ) %>%
    unlist() ->
    predElection2020_b$地區
  
  attr(predElection2020_b, "data source") <- dataSource

  predElection2020_b %>%
    group_by(
      地區
    ) %>%
    mutate(
      地區票數=sum(得票數)
    ) %>%
    ungroup() -> predElection2020rev
}

各地區得票率統計

predElection2020rev %>%
  group_by(號次, 地區) %>%
  summarise(
    得票率=sum(得票數)/sum(地區票數)
  ) %>% 
  ungroup() -> df_byCounty

8.2.3 基本設計:單一地區

# 基本設計
ggByCounty <- function(Xdata){
  ggplot(
    data=Xdata
  ) +
  geom_col(
    aes(
      x=號次, y=得票率, fill=號次
    )
  )
}
df_byCounty %>%
  filter(地區=="新北市") %>%
  ggByCounty()

8.2.4 切圖

df_byCounty %>%
  # 刪除
  # filter(
  #   地區=="新北市"
  # ) %>%
  ggplot() +
  geom_col(
    aes(
      x=號次, y=得票率, fill=號次
    )
  ) +
  # 加上
  facet_wrap(
    vars(地區)
  )

8.3 Facet grid (雙切面圖)

facet_grid in 3 steps

8.4 2012-2020總統大選

目標 藍綠兩黨在北部各縣市的三次大選得票率走勢

8.4.1 資料來源處理

predElection2012<- readxl::read_excel("~/Dropbox/github-data/109-1-econDV/election2012.xls")
predElection2016 <- readxl::read_excel("~/Dropbox/github-data/109-1-econDV/election2016.xls")
fix_electionData <- function(predElection2020){
  predElection2020 %>%
    filter(
      !is.na(號次)
    ) -> predElection2020_b
  predElection2020_b$地區 %>%
    na.omit() %>%
    purrr::map(
      ~{rep(.x,3)}
    ) %>%
    unlist() ->
    predElection2020_b$地區
  
  attr(predElection2020_b, "data source") <- dataSource

  predElection2020_b %>%
    group_by(
      地區
    ) %>%
    mutate(
      地區票數=sum(得票數)
    ) %>%
    ungroup() -> predElection2020rev
}
predElection2012rev <- fix_electionData(predElection2012)
predElection2016rev <- fix_electionData(predElection2016)

8.4.2 Pseudo-codes

electionDataMerged <- {
  
}
ggfacet_base_function <- function(Xdata)(
  ggplot(
    data=Xdata,
    mapping=aes(
        x=year,
        y=得票率
      )
    ) +
    geom_point() +
    geom_line()
)
ggfacet_base <- {
  electionDataMerged %>%
    filter(
      party=="dpp", 地區=="新北市"
    ) %>%
    ggfacet_base_function()
}
ggfacet_2012_2020elections <- {
  electionDataMerged %>%
    ggfacet_base_function() +
    facet_grid(
      rows=vars(地區),
      cols=vars(party)
    )
}

8.4.3 資料整理

electionDataMerged <- {
  predElection2020rev$year = 2020
  predElection2012rev$year = 2012
  predElection2016rev$year = 2016
  
  electionDataMerged <- 
    dplyr::bind_rows(
      predElection2012rev, predElection2016rev, predElection2020rev
    )
  electionDataMerged$姓名 %>% factor() ->
    electionDataMerged$party
  levels(electionDataMerged$party) <- c("pfp", "kmt", "dpp", "kmt", "kmt")
  
  electionDataMerged %>%
    mutate(
      地區 = dplyr::if_else(地區=="桃園縣", "桃園市", 地區)) ->
    electionDataMerged
  
  electionDataMerged %>%
    filter(
      party != "pfp",
      stringr::str_detect(地區,"北|桃|基|竹")
    ) -> electionDataMerged

  
  electionDataMerged
}

8.4.4 基本設計

ggfacet_base_function = function(Xdata)(
  ggplot(
    data=Xdata,
    mapping=aes(
        x=year,
        y=得票率
      )
    ) +
    geom_point() +
    geom_line() +
    scale_x_continuous(
      breaks=c(2012, 2016, 2020),
      labels=c(2012, 2016, 2020)
    )
)
electionDataMerged %>%
  filter(
    party=="dpp", 地區=="新北市"
  ) %>%
  ggfacet_base_function()

8.4.5 切圖

ggfacet_2012_2020elections <- {
  electionDataMerged %>%
    ggfacet_base_function() +
    facet_grid(
      rows=vars(地區),
      cols=vars(party)
    ) +
    theme_bw()
}

8.5 更多facet_grid的使用

8.6 KMT北中南東各區得票率

8.6.1 Pseudo-codes

electionKmtWithRegions <- {
  
  
}

# 基本設計
ggfacet_base_regional <- function(Xdata){
  ggplot(
    data=Xdata,
    aes(
      x=地區, 
      y=得票率,
      fill=region
    )
  )
}
electionKmtWithRegions %>%
  filter(
    region=='北部'
  ) %>% #View()

# 切圖
ggfacet_electionByRegion <- {
  electionKmtWithRegions %>%
    ggfacet_base_regional() +
    facet_grid(
      cols=vars(region)
    )
  
  
}

8.6.2 資料整理

predElection2020rev$year = 2020
predElection2012rev$year = 2012
predElection2016rev$year = 2016

electionDataMerged <- 
  dplyr::bind_rows(
    predElection2012rev, predElection2016rev, predElection2020rev
  )
electionDataMerged$姓名 %>% factor() ->
  electionDataMerged$party
levels(electionDataMerged$party) <- c("pfp", "kmt", "dpp", "kmt", "kmt")

electionDataMerged %>%
  mutate(
    地區 = dplyr::if_else(地區=="桃園縣", "桃園市", 地區)) ->
  electionDataMerged

electionDataMerged %>%
  filter(
    year == 2020
  ) -> electionDataMerged2020

  
electionDataMerged2020 %>%
  filter(
    party=="kmt"
  ) %>%
  mutate(
    region =
      dplyr::case_when(
        stringr::str_detect(地區,"[北基竹桃宜]") ~ "北部",
        stringr::str_detect(地區,"[中苗彰投雲]") ~ "中部",
        stringr::str_detect(地區,"[高南嘉屏澎]") ~ "南部",
        TRUE ~ "東部" # 其他
      )
  ) -> electionKmtWithRegions

8.6.3 基本設計

ggfacet_base_regional <- function(Xdata){
  ggplot(
    data=Xdata,
    aes(
      x=地區, 
      y=得票率,
      fill=region
    )
  ) +
  geom_col() +
  coord_flip()
}
electionKmtWithRegions %>%
  filter(
    region=='北部'
  ) %>% #View()
  ggfacet_base_regional()

8.6.4 切圖

electionKmtWithRegions %>%
  ggfacet_base_regional() +
  facet_grid(
    rows=vars(region)
  ) 

electionKmtWithRegions %>%
  ggfacet_base_regional() +
  facet_grid(
    rows=vars(region),
    scales = "free_y"
  ) 

electionKmtWithRegions %>%
  ggfacet_base_regional() +
  facet_grid(
    rows=vars(region),
    scales = "free_y", 
    space = "free_y"
  ) + theme_classic()

8.7 stat_summary