---
image: https://hackmd.io/_uploads/ryeP8Grgbp.png
---
# 用R做年度每日氣溫圖
###### tags: `用R做`,`學習筆記`
之前用R做過[氣候圖](/k8S0DAi5Sle1-w-_VGT8pQ),這次換個視覺化的方法,繪製全年的每日氣溫分布圖。從圖中可以快速了解一年當中每天的高、低溫與平均溫度。
一開始,當然要從氣象署的[觀測資料查詢系統](https://e-service.cwb.gov.tw/HistoryDataQuery/)抓出每天的氣溫資料。以下用已撤銷的香山測站為例,參考[阿好伯的做法](https://hackmd.io/@LHB-0222/Wind_Rose),抓出設站開始到撤銷之前完整年的資料:
```java=
library(dplyr)
library(jsonlite)
library(rvest)
library(magrittr)
library(lubridate)
library(ggplot2)
library(lubridate)
#載入資料,站名記得換
url_start <- "https://e-service.cwb.gov.tw/HistoryDataQuery/DayDataController.do?command=viewMain&station=C0D570&stname=%25E9%25A6%2599%25E5%25B1%25B1&datepicker="
#先寫自訂函式
climatecrawler <- function(x,y){
start_date <- as.Date(x)
end_date <- as.Date(y)
date_seq <- seq(start_date, end_date, by = "days")
date_seq_str <- as.vector(format(date_seq, "%Y-%m-%d"))
data1 <- data.frame()
data2 <- data.frame()
for(single_date in date_seq_str){
url <- paste0(url_start, single_date, "&altitude=15m") #高度計得換
temp <- url %>%
read_html() %>%
html_nodes(xpath = '//*[(@id = "MyTable")]//td[(((count(preceding-sibling::*) + 1) = 4) and parent::*)]') %>%
html_text(trim = T) %>%
gsub("X", "-9999", .) %>%
as.numeric()
data1 <- cbind(date = single_date, ta = mean(temp), tn = min(temp), tx = max(temp))
data2 <- rbind(data2, data1)
}
return(data2)
}
#可以開始抓資料了
HSClimate_20071201_20211130 <- climatecrawler("2007-12-01", "2021-11-30")
write.csv(HSClimate_20071201_20211130, "香山測站20071201_20211130觀測資料.csv")
```
資料抓完,就可以開始視覺化。這邊從讀取 .csv 開始,當然也可以連著上面直接用抓好的資料接著做。
```java=
HSdf <- read.csv("香山測站20071201_20211130觀測資料.csv", header = T, row.names = 1)
HSdf <- na.omit(HSdf)
HSdf$day <- yday(HSdf$date)
HSdf.o <- aggregate(HSdf[2:4], HSdf["day"], mean)
HSdf.o <- mutate(HSdf.o, day = as_date(day, origin = "1999-12-31"))
col_temp <- c("#0b144f","#0e2680","#223b97","#1c499a","#2859a5",
"#1b6aa3","#1d9bc4","#1ca4bc","#64c6c7","#86cabb",
"#91e0a7","#c7eebf","#ebf8da","#f6fdd1","#fdeca7",
"#f8da77","#fcb34d","#fc8c44","#f85127","#f52f26",
"#d10b26","#9c042a","#760324","#18000c")
ggplot(HSdf.o) +
geom_linerange(aes(day, ymax = tx, ymin = tn, colour = ta), linewidth = .8, alpha = .7) +
scale_y_continuous(breaks = seq(0, 40, 10), limits = c(0, 40), expand = expansion()) +
scale_colour_gradientn(colours = col_temp, limits = c(10, 30), breaks = seq(10, 35, 5)) +
scale_x_date(date_breaks = "month", date_labels = "%b") +
labs(title = "香山氣象站2007-2021全年日溫變化", colour = "日均溫") +
theme_minimal(base_size = 12) +
theme(plot.title = element_text(size = 14), axis.title.x = element_blank(), panel.grid.minor = element_blank())
```
主要就是把資料依據 1–366 日,把各年的高、低、均溫平均,再找一個閏年(這邊用 2000 年)塞進去,用該年度的日期作為 x 軸。y 軸當然就是溫度了,以每日低溫與高溫決定線段長度,並依照每日均溫上色(視覺化的程式碼與色票參考自[此](https://www.r-bloggers.com/2021/09/climate-circles/?fbclid=IwAR3zil87S00U2iIQQxaWn-z9-7ZUewWbirvWj59IdZtoLOeMitkZKomd4Xg))。
做出來的效果就像下圖:

<br>
如果加上 `coord_polar()`,就可以把圖轉換一個圓:

一開始抓的資料,包含四年一度的 2 月 29 日,過少的資料會讓平均值和相鄰的日期不同,可以把這天去掉。如果把 2 月 29 日去除,那在 `as_date()` 指令中,就需要選擇一個非閏年,日數才對得上。
<span style="font-size:30px">🐕🦺</span><font color="dcdcdc">2023.10.08</font>