關於setTimeout, setInterval, clearTimeout, clearInterval

參考自

https://kuro.tw/posts/2019/02/23/%E8%AB%87%E8%AB%87-JavaScript-%E7%9A%84-setTimeout-%E8%88%87-setInterval/

https://developer.mozilla.org/zh-TW/docs/Web/API/setInterval

1.setTimeout():設定的時間相當於倒數計時的計時器,當所設定的時間(毫秒)到時,便會執行指定的函數(只會執行一次),後續可以使用 clearTimeout()來清除。
常用的用法是setTimeOut(執行的函數名稱,時間);

2.setInterval():設定的時間是一段間隔時間,會間隔我們設定的時間執行函數(不斷執行),後續可以使用clearInterval()來清除

實做:背景圖片輪播(無限循環)

都屬於非同步事件,由於JS是單執行緒語言,且JS中的非同步事件(例如setTimeout, setInterval, ajax)的 callback function 被呼叫時,會將 callback function 的任務丟到 Event Queue 當中,並等待目前 Stack 的任務都已經完成後,再繼續逐一執行 Event Queue 的任務。因此設定的時間只能表現為最少時間,而非精準的時間

使用vertical-align: middle 達成垂直置中

工作上除了新案開發外,維護既有專案細部調整版面時也常有垂直置中的需求,尤其是維護既有系統時,如何不影響原本HTML架構之下,僅更動到要改變的區塊,紀錄兩個常用方法,並複習 vertical-align: middle; 的適用場合。

vertical-align常用於<img> ,因此使用vertical-align: middle;但效果不如預期時,必須注意這個屬性適用於display: inline-block 或是 table-cell

被垂直置中的元素為 inline-block其父層必須設定高度;如果屬性為table-cell,那麼父層屬性必須是table且須設定高度。這篇延伸閱讀介紹得非常清楚。

工作中常見的需求是垂直置中sidemenu中的menu-item,且此 sidemenu本身屬性為 position:absolute作為例子,由於使用絕對定位的元素會脫離normal flow,所以無法使用應用position:relative的垂直置中技巧。

整理出使用時的注意事項:

1.被垂直置中的元素本身屬性必須是 inline-block或table-cell

2.被垂直置中的元素其父層必須設定高度。

inline-block屬性結合偽元素的做法

table-cell屬性的做法

Linux 快速鍵與常用指令

先存一些實用的網站,之後再做閱讀筆記。

#1 scp本機或遠端主機的檔案傳輸(遠端的 Linux 主機必須要開啟 SSH 遠端登入服務)

在本機上使用 cp 複製檔案,用 mv 複製並移動資料夾,跨 server 之間可以使用scp指令來做傳輸。

#2 常用Linux指令與快捷鍵

https://www.mropengate.com/2018/01/linuxunix-cheat-sheet-for-linuxunix.html

使用PHP連接MongoDB

做專案實際遇到的需求,客戶device的資料透過gateway傳進MongoDB,想將device的能耗呈現在網頁,在後端語言與存放數據資料庫既定的情況下,研究了PHP控制MongoDB的做法。

研究完的結論就是之後要找時間學Node.js

因為MongoDB官方和PHP官方建議的driver並不相同,MongoDB官方的’high level’ driver有些方法已經棄用,踩了不少雷,且用PHP官方的driver速度比MongoDB官方driver快……故記錄下來。

最後我選擇使用PHP官方文件的driver,雖然這套driver僅支援較簡易的操作,不過對於我目前需求很夠用。

PHP官方建議的步驟,前置作業先安裝composer這個套件管理軟體,用composer下載與管理與此專案相依的php 套件,再打開php.ini 啟用extension=php_mongodb.dll,再檢查一下你的ext的資料夾中有沒有php_mongodb.dll
然後看一下phpinfo(),成功的話將看到mongoDB的套件資訊。

然後直接看code吧。

<?php
//https://www.php.net/manual/en/class.mongodb-driver-query.php
$mongodb_server = 'yourserver';  
$mongodb_password = 'yourpassword'; 
$mongodb_user = 'username';
$manager = new MongoDB\Driver\Manager("mongodb://$mongodb_server",array("username" => $mongodb_user, "password" => $mongodb_password));

//$manager = new MongoDB\Driver\Manager('mongodb://localhost:27017');
?>

gitignore使用雜記

近日整理一些作品集,發現上傳到github公開的倉庫上需要注意避免將資料庫密碼等機密檔案上傳,這個因為在前公司都是上傳到公司自行架設的GitLab,比較沒注意,趁機複習一下gitignore的使用。

  • 使用上我們可以先 touch .gitignore,然後直接在gitignore裡面新增我們要git忽略的檔案或資料夾名稱,列在gitignore的檔案不會受版本控制。
  • 但是如果你的檔案在建立.gitignore之前就已經存在了,.gitignore對這些檔案沒有作用。要移除這些已存在檔案的版本控制,可以使用git rm --cached 檔案名稱將這些檔案移出git的版控範圍
  • 或是在stage file時,只將要版控的檔案加進工作目錄;或是git restore 檔案名稱 (此指令會discard 檔案的變更)都是一種方法。

下面是關於gitignore的一些實用文章,謝謝這些文章作者。

【狀況題】有些檔案我不想放在 Git 裡面…

【Git】檔案管理 – 忽略檔案 .gitignore

Git 學習筆記_03(使用Git指令 – 2)

OpenWeather API 串接

為面試公司(產品是飯店IP TV的系統)客製作品集,將目前所在地區的天氣顯示在網頁上。

研究後發現3.0版雖然有免費的方案,但是還是要個別訂閱每種呼叫的api比較麻煩,最後改用2.5版的API

首先註冊,註冊後系統會發確認函到註冊的email,點擊確認函後系統才會activate帳號對應的API ID,但不一定馬上可以使用,等待時間從數小時到一整天不等。

當帳號activate後系統也會自動發送預設的API ID,並且附上官方教學文件。

使用的是axios套件,留意要先引入。

        
function getWeather(){
            axios.get(
                'https://api.openweathermap.org/data/2.5/weather?lat=22.63&lon=120.30&units=metric&appid={這裡放API ID}&lang=zh_tw'
            )
            .then(response => {
                let thisData = response.data;
                let city = document.querySelector('#city');
                let temperature = document.querySelector('#temperature');
                let feel = document.querySelector('#feel');
                let weather = document.querySelector('#weather');
                let icon = document.querySelector('#icon');
                let sunrise = document.querySelector('#sunrise');
                let sunset = document.querySelector('#sunset');
                city.textContent = thisData.name;
                temperature.textContent = thisData.main.temp;
                feel.textContent = thisData.main.feels_like;
                weather.textContent = thisData.weather[0].description;
                icon.src = `http://openweathermap.org/img/w/${thisData.weather[0].icon}.png`;
                sunrise.textContent = new Date(thisData.sys.sunrise*1000).toLocaleTimeString();
                sunset.textContent = new Date(thisData.sys.sunset*1000).toLocaleTimeString();
            })
            .catch(error => {
                console.log(error);
            }) 
        };

將網頁轉為SVG檔並且自動下載

實作專案中的客戶需求:將網頁上所顯示的表格轉為SVG檔,且按鈕就能下載這個檔案。分成兩大步驟來達成功能。

230715補充說明下,最後是轉為png檔,沒有使用SVG檔,因為轉出的SVG檔雖可以在瀏覽器正常顯示,但表格中文字與表格框線都無法在設計工具(客戶用Adobe Illustrator)顯示, Illustrator只有看到SVG檔中image的部分,猜測是因為Adobe Illustrator這類設計軟體只接受正統的SVG結構(這個套件原理是用<foreignObject>嵌在SVG中)。

轉成png檔的方法也是直接用此套件提供的方法,一樣依照Github上的官方範例就可以實現功能。

function downloadPNG(dataUrl, filename) {
    const link = document.createElement('a');
    link.href = dataUrl;
    link.download = filename;
    link.click();
}
function png2File(){
    htmlToImage.toPng(document.getElementById('divList'))
    .then(function (dataUrl) {
        console.log(dataUrl);
        const outputFileName = 'yourFileName';
        downloadPNG(dataUrl, outputFileName);
});
}  

1.將DOM轉為svgDataUrl:使用html-to-image套件

function svg2DataUrl(){
            function filter (node) {
                return (node.tagName !== 'i');
            }
            // html to svgURL
            htmlToImage.toSvg(document.getElementById('divList'), { filter: filter })
            .then(function (dataUrl) {
                console.log(dataUrl);
                const outputFileName = 'SVG';
                svgDataUrlToFile(dataUrl, outputFileName);

            })
            .catch(function (error) {
                console.error('oops, something went wrong!', error);
            });
    }

2.將svgDataUrl轉成svg檔後下載

    function svgDataUrlToFile(svgDataUrl, outputFileName) {
        // parsing SVG Data URL
        const encodedData = svgDataUrl.substring("data:image/svg+xml;charset=utf-8,".length);
        const decodedData = decodeURIComponent(encodedData);

        // create Blob obj
        const blob = new Blob([decodedData], { type: "image/svg+xml" });

        // create downloadLink element
        const downloadLink = document.createElement("a");
        downloadLink.href = URL.createObjectURL(blob);
        downloadLink.download = outputFileName;
        console.log(downloadLink);
        // click downloadLink
        downloadLink.click();
    }

AJAX POST API 講解

六角js班的筆記

https://developer.mozilla.org/zh-TW/docs/Web/HTTP/Methods

Get和Post的不同:
Post:瀏覽器會傳送資料給伺服器,讓server回傳資料正確or錯誤or其他狀態。
Get:get只用於取得資料。

Post網路請求格式介紹:
Method :代表HTTP請求方法
URL:向哪一個網址發送請求
Data:資料的格式/(屬性)
***發送請求時,需要依照指定的格式傳送,才能要到資料

四種常見的 POST 請求 content-type (request的資料內容的格式)介紹:
request header Content-Type
1.application/x-www-form-urlencoded→提交表單的那種格式
2.application/json→json格式
3.multiple/form-data→需要的是檔案(例如pdf、mp4)的資料格式
4.text/plain→單純文字,較少使用
**前端工程師向後端工程師要資料時,需要問清楚content-type

透過axio套件,實做網路請求,本小節練習用 API 網址

// axios API
axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
// 放要post的資料結構
  .then(function (response) {
    console.log(response);
  })
//如果成功,就跑then
  .catch(function (error) {
    console.log(error);
  });
//如果失敗,就跑catch
// AJAX POST API 講解:透過axios實作 註冊POST 網路請求
// 可以從Chrome dev tool 的 Network裡面觀察到
// axios這個套件,需額外載入JS
// axios
// Using jsDeliver CDN(下載站點)
let obj ={
    email: 'gg@gmail.com',
    password: '12345678'
}

axios.post('https://hexschool-tutorial.herokuapp.com/api/signup', obj)
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

R for Data Science Ch 7.6 – 7.8

7.6 Patterns and models
若觀察到變數之間的趨勢(pattern),代表兩變數可能具有某種關係,即兩變數存在共變性(covariation)。當我們觀察到趨勢,要注意以下五點:

  1. 趨勢是否僅偶然發生?
  2. 如何描述趨勢隱含的兩變數關係?
  3. 趨勢隱含的兩變數關係強度多強?
  4. 是否有別的變數影響兩變數間的關係?
  5. 取出數據中的 subgroup 觀察,subgroup之間的關係是否和整體趨勢一致?

以下範例是老忠實噴泉噴發時間長度(eruption length)與每次噴發的間隔時間(the wait time between eruptions)的散佈圖(scatterplot):

ggplot(data = faithful) + 
  geom_point(mapping = aes(x = eruptions, y = waiting))

由上圖可看出越長的噴發時間似乎有越長的噴發時間間隔,且在圖片的右上角與左下角發現兩個集群(cluster)。

在圖中觀察到趨勢,顯示兩變數間具有共變性,如果變異性(variation)是不確定性(uncertainty)所展現出的現象,那麼共變性就是能夠減少不確定性的現象。若我們知道兩變數共變,就能夠取其中一個變數的觀察值(???或許翻作特定值較好???)預測另一個變數的預測值。若共變性是來自兩變數之間的因果關係,就能夠取其中一個變數的觀察值控制另一個變數的對應值。

而模型(Model)則是從數據中萃取出趨勢的工具。Models are a tool for extracting patterns out of data. 

讓我們看看以下的例子,在 diamonds 數據集中,由於 「cut」與「carat」之間的強烈關係,使得我們不容易看出「cut」與「price」之間的關係。因為「cut」與「carat」、「carat」與「price」之間有緊密的關係,我們可以先移除「carat」與「price」之間的關係,再畫出「cut」與「price」之間的趨勢。

先做變數轉換使「carat」與「price」之間呈現線性關係,再計算以「carat」預測「price」的殘差(residuals)。注意:The residuals give us a view of the “price" of the diamond, once the effect of “carat" has been removed.
以下面程式區塊實作之:

# fits a model that predicts price from carat 
# and then computes the residuals (the difference between the predicted value and the actual value) ---


library(modelr)

# log transformation makes the pattern linear
mod <- lm(log(price) ~ log(carat), data = diamonds)

# add column "resid"
diamonds2 <- diamonds %>% 
  add_residuals(mod) %>% 
  mutate(resid = exp(resid))

# the following scatterplot show that the strong relationship between carat and price 
# have removed (?????)
ggplot(data = diamonds2) + 
  geom_point(mapping = aes(x = carat, y = resid))
# the relationship between "cut" and "price"
ggplot(data = diamonds2) + 
  geom_boxplot(mapping = aes(x = cut, y = resid))
# relative to their size, better quality diamonds are more expensive
# 然而我覺得以肉眼來看關係沒有很強......

在本書的後續章節(第二十二章至第二十五章)會針對建模做更深入的探討。

7.7 ggplot2 calls
即將離開以往的introductory chapters 前夕,針對往後使用到 ggplot2 package 程式碼的書寫,作者在此小節交代了與讀者們的默契:The first two arguments to ggplot() are data and mapping, and the first two arguments to aes() are x and y
以下兩塊等價的程式區塊為範例:

ggplot(data = faithful, mapping = aes(x = eruptions)) + 
  geom_freqpoly(binwidth = 0.25)
# rewriting the previous plot more concisely
ggplot(faithful, aes(eruptions)) + 
  geom_freqpoly(binwidth = 0.25)

並且再次注意,由於 ggplot2 是在 pipe 運算子之前創造的package,務必小心 %>%+ 兩種符號的連接。

7.8 Learning more
如果想深入學習活用 ggplot2 ,作者推薦了自己寫的書:ggplot2: Elegant Graphics for Data Analysis,以及下列兩本其他大大的著作:
http://www.cookbook-r.com/Graphs/
https://www.amazon.com/dp/1498715230/ref=cm_sw_su_dp

R for Data Science 7.5.2 – 7.5.3

7.5.2 Two categorical variables

兩類別變數的視覺化,需要先計算各情況組合的累計數 (count),使用內建的geom_count() 函數實作此功能。

ggplot(data = diamonds) +
  geom_count(mapping = aes(x = cut, y = color))

上圖的資料點大小與觀察值個數成正比。

另一種方式呈現兩類別變數關係:先以dplyr 包計算總計數(count),再用geom_tile() 視覺化。

diamonds %>% 
  count(color, cut)
#> # A tibble: 35 x 3
#>   color cut           n
#>   <ord> <ord>     <int>
#> 1 D     Fair        163
#> 2 D     Good        662
#> 3 D     Very Good  1513
#> 4 D     Premium    1603
#> 5 D     Ideal      2834
#> 6 E     Fair        224
#> # … with 29 more rows
diamonds %>% 
  count(color, cut) %>%  
  ggplot(mapping = aes(x = color, y = cut)) +
    geom_tile(mapping = aes(fill = n))

seriation 包可以同時 reorder 兩類別變數的行與列,d3heatmap 包 或 heatmaply 包可以進一步產生互動式圖表 ( interactive plots )。

7.5.2.1 Exercises


How could you rescale the count dataset above to more clearly show the distribution of cut within color, or color within cut?

先計算出「cut」變數之下每個 level 之下,每種 level 的 「color」所佔的比例,再以 geom_tile() 繪製 heatmap(???).

# show the distribution of cut within color

library(viridis)
diamonds %>%
  count(color, cut) %>%
  group_by(color) %>%
  mutate(prop = n / sum(n)) %>%
  ggplot(mapping = aes(x = color, y = cut)) +
  geom_tile(mapping = aes(fill = prop)) +
  scale_fill_viridis(limits = c(0, 1)) # from the viridis colour palette library
# show the distribution of color within cut
diamonds %>%
  count(color, cut) %>%
  group_by(cut) %>%
  mutate(prop = n / sum(n)) %>%
  ggplot(mapping = aes(x = color, y = cut)) +
  geom_tile(mapping = aes(fill = prop)) +
  scale_fill_viridis(limits = c(0, 1))

scale_fill_viridis(limits = c(0, 1)) 限制圖片比例介於零到一之間,這也是我們所知數學上比例的範圍,限制顯示單位方便跨圖片的比較,但可能不利於單一圖片內各 level 組合之間的比較;反之若使用預設尺度(顯示全距),則方便單一圖片內各 level 組合之間比較,但不利於跨圖片比較。

Exercise 7.5.2.2


Use geom_tile() together with dplyr to explore how average flight delays vary by destination and month of year. What makes the plot difficult to read? How could you improve it?

# how average flight delays vary by destination and month of year?
library("nycflights13")
flights %>%
  group_by(month, dest) %>%
  summarise(dep_delay = mean(dep_delay, na.rm = TRUE)) %>%
  ggplot(aes(x = factor(month), y = dest, fill = dep_delay)) +
  geom_tile() +
  labs(x = "Month", y = "Destination", fill = "Departure Delay")

有三點可以改進上圖:
1. 將「dest」以有意義的方式排序分組(sorted),如依據飛行里程數、該地點降落班機數目、平均延遲時間……等等。
2. 移除遺漏值 ( missing value )
3. 更好的 color schema (使用 viridis 包)

library("nycflights13")
library(viridis)
flights %>%
  group_by(month, dest) %>%
  summarise(dep_delay = mean(dep_delay, na.rm = TRUE)) %>%
# set (na.rm = TRUE) to remove missing value
  group_by(dest) %>%
  filter(n() == 12) %>%
# (84 different levels of "dest") * (sample size = 12)
  ungroup() %>%
  mutate(dest = reorder(dest, dep_delay)) %>%
  ggplot(aes(x = factor(month), y = dest, fill = dep_delay)) +
  geom_tile() +
  scale_fill_viridis() +
  labs(x = "Month", y = "Destination", fill = "Departure Delay")

Exercise 7.5.2.3

Why is it slightly better to use aes(x = color, y = cut) rather than aes(x = cut, y = color) in the example above?

通常我們會將類別個數 (level 數)較多的類別變數,或是類別名稱字數較長的類別變數放置在縱軸 (y-axis)。為了閱讀的方便性,在命名標籤不互相重疊的前提下,盡可能讓命名標籤(即,類別變數之下各個 level 名稱)以水平方向顯示。

# aes(x = cut, y = color)
diamonds %>%
  count(color, cut) %>%
  ggplot(mapping = aes(y = color, x = cut)) +
  geom_tile(mapping = aes(fill = n))
# aes(y = cut, x = color)
diamonds %>%
  count(color, cut) %>%
  ggplot(mapping = aes(x = color, y = cut)) +
  geom_tile(mapping = aes(fill = n))

7.5.3 Two continuous variables
我們可以使用散佈圖 (scatter plot) 描繪兩連續變數的關係,以geom_point() 函數繪製散佈圖。

ggplot(data = diamonds) +
  geom_point(mapping = aes(x = carat, y = price))

# an exponential relationship between "carat" and "price"

隨著數據量增大,散佈圖容易有 overplot 與 資料點堆積在某一特定區域的缺點,可以透過調整透明度,即設定 aesthetic 中的 alpha 數值來改進。

ggplot(data = diamonds) + 
  geom_point(mapping = aes(x = carat, y = price), alpha = 1 / 100)

當調整透明度也無法優化數據量大的散佈圖時,可以使用裝箱法 (bin,或譯組界、格子大小):以geom_bin2d() 和 geom_hex() 函數實作二維的裝箱 (bin in two dimensions)。
先前章節中我們使用過的geom_histogram() and geom_freqpoly() 則是一維的裝箱 (bin in one dimension)。

geom_bin2d() 和 geom_hex() 函數會將座標平面分割成 2d bins,接著對 bins 填滿上色,bins 的顏色代表落在每一個 bin 中的資料點個數。geom_bin2d() 函數產生矩形bins;geom_hex() 函數產生六角形 bins,留意必須安裝hexbin 包才能使用geom_hex() 函數。

ggplot(data = smaller) +
  geom_bin2d(mapping = aes(x = carat, y = price))
# Error in ggplot(data = smaller) : object 'smaller' not found
# 遍尋不著 "smaller" 這個 dataset

# install.packages("hexbin")
ggplot(data = smaller) +
  geom_hex(mapping = aes(x = carat, y = price))
# Error in ggplot(data = smaller) : object 'smaller' not found
geom_bin2d( )
geom_hex( )

另一個方法是將其中一個連續型變數裝箱為類別變數,接著可以使用 7.5.1 章節的方法將兩變數視覺化。以下範例將「carat」bin 成類別變數後繪製箱型圖 ( boxplot )。

ggplot(data = smaller, mapping = aes(x = carat, y = price)) + 
# 依舊找不到 smaller 這個 dataset
  geom_boxplot(mapping = aes(group = cut_width(carat, 0.1)))
# cut "carat" into bins of width = 0.1

預設每個箱型圖都大小一致,以下方法可以讓箱型圖大小隨著箱型圖中所包含的觀察值數目同方向變化(make the width of the boxplot proportional to the number of points with varwidth = TRUE)。
或是使用cut_number() 函數:讓每個bin中的觀察值個數大約一致。

ggplot(data = smaller, mapping = aes(x = carat, y = price)) + 
  geom_boxplot(mapping = aes(group = cut_number(carat, 20)))

7.5.3.1 Exercises
比較cut_width() 與 cut_number() :這兩種函數都是用來將變數分割為多個group,使用cut_width() 函數,需要設定間距 (width),每個 bin 中的觀察值個數則是會被自動設定;使用cut_number() 時,需要設定組別數,間距則會被自動設定。
當 width 與 number 設定值越大時,越助於匯集觀察值以消弭噪音 (aggregate observations to remove noise),但需要注意設定值過大時會使所有訊號消失。

繪圖時若以不同顏色代表不同組別時,注意一張圖中不要超過八種顏色以利肉眼辨識。

以下使用cut_number()函數,將「carat」分成五組:

ggplot(
  data = diamonds,
  mapping = aes(color = cut_number(carat, 5), x = price)
) +
  geom_freqpoly() +
  labs(x = "Price", y = "Count", color = "Carat")

下面程式區塊則是使用cut_width()函數,由於間距若設定0.5,則有太多分組數,且超過 2 carat 的觀察值個數不多,我們設定間距為 1-carat widths.

ggplot(
  data = diamonds,
  mapping = aes(color = cut_width(carat, 1, boundary = 0), x = price)
) +
  geom_freqpoly() +
  labs(x = "Price", y = "Count", color = "Carat")

Exercise 7.5.3.2

Visualize the distribution of carat, partitioned by price.

#Plotted with a box plot with 10 bins with an equal number of observations
ggplot(diamonds, aes(x = cut_number(price, 10), y = carat)) +
  geom_boxplot() +
  coord_flip() +
  xlab("Price")
# The argument "boundary = 0" ensures that first bin is $0–$2,000.
# The argument "varwidth = TRUE" 
# make the width of the boxplot proportional to the number of points. ---
ggplot(diamonds, aes(x = cut_width(price, 2000, boundary = 0), y = carat)) +
  geom_boxplot(varwidth = TRUE) +
  coord_flip() +
  xlab("Price")

Exercise 7.5.3.3
觀察範例 7.5.3.1的兩張折線圖,可以看出大克拉數(carat )的鑽石相較小克拉數的鑽石,在價格上有更大的分散趨勢(變異程度更大,more variable),可能是因為小克拉數鑽石必須在切割工藝 (cut)、淨度 (clarity)、顏色 (color) 上達到一定水準才賣得出去,所以小克拉鑽石的同質性相較大克拉鑽石更高。大克拉鑽石本身條件就比較有利可圖,因此在切割工藝、淨度、顏色等其他條件(自變數)上參差不齊(more variable)。

*****Exercise 7.5.3.4*****

Combine two of the techniques you’ve learned to visualize the combined distribution of cut, carat, and price.

當然有非常多方法視覺化這三個變數,以下列出作者的示範:

# faceted hexagonal heatmap of 2d bin counts, faceted geom_hex() ---
install.packages("hexbin")
library(viridis)
ggplot(diamonds, aes(x = carat, y = price)) +
  geom_hex() +
  facet_wrap(~cut, ncol = 1) +
  scale_fill_viridis()
ggplot(diamonds, aes(x = cut_number(carat, 5), y = price, color = cut)) +
  geom_boxplot()
# 相較於上一個方法,將 "carat" 離散化後作為上色變數,更能看出大克拉鑽石在價格上的異質性
ggplot(diamonds, aes(color = cut_number(carat, 5), y = price, x = cut)) +
  geom_boxplot()

*****Exercise 7.5.3.5*****

Two dimensional plots reveal outliers that are not visible in one dimensional plots. For example, some points in the plot below have an unusual combination of x and y values, which makes the points outliers even though their x and y values appear normal when examined separately.

離群值 (outlier) 之檢測:某些只觀察單一維度不會發現的離群值(binned-boxplot 不會發現的離群值),繪製在二維平面以兩變數共同觀察時(繪製scatterplot),才會顯示出不尋常的落點。如以下範例:

ggplot(data = diamonds) +
  geom_point(mapping = aes(x = x, y = y)) +
  coord_cartesian(xlim = c(4, 11), ylim = c(4, 11))

注意極大的 x 值卻落在配適迴歸線上,也就是 x 變數中的離群值卻配適雙變數整體趨勢。(the largest value of xx was an outlier even though it appears to fit the bivariate pattern well.)

使用 WordPress.com 設計專業網站
立即開始使用