如何使用 ggplot2 ?
我也來佔個坑吧。。。我主要講理念的東西,希望大家有一定經驗的再來看此答案。
總結來說有以下幾點:- ggplot2的核心理念是將繪圖與數據分離,數據相關的繪圖與數據無關的繪圖分離
- ggplot2是按圖層作圖
- ggplot2保有命令式作圖的調整函數,使其更具靈活性
- ggplot2將常見的統計變換融入到了繪圖中。
==================================================================
1、ggplot2的邏輯。
ggplot2的邏輯在我看來其實是真正實現了一個圖層疊加的概念:一句語句代表一張圖,然後再有最小的單元圖層。這個與其他命令式的繪圖完全不同,來做個比較:
#這是基於graphic包里例子
x &<- rnorm(100,14,5)
y &<- x + rnorm(100,0,1)
plot(x,y)
text(13,20, expression(x[1] == x[2]))
輸出的圖是這樣的:
我們可以看到這種繪圖方式實際上是按命令添加的,以plot開始,可以以任何方式結束,每加上一個元素,實際上都是以一句單獨的命令來實現的。這樣做的缺點就是,其實不符合人對於畫圖的一般認識。其次,就是,我們沒有一個停止繪圖的標誌,這使得有時候再處理的時候就會產生一些困惑。優勢其實也有,在做參數修改的時候,我們往往可以很方便地直接用一句單獨的命令修改,譬如對於x軸的調整,覺得不滿意就可以寫命令直接調整。而ggplot2則意味著要重新作圖。再來看ggplot2的代碼:
x &<- rnorm(100,14,5)
y &<- x + rnorm(100,0,1)
ggplot(data= NULL, aes(x = x, y = y)) + #開始繪圖
geom_point(color = "darkred") + #添加點
annotate("text",x =13 , y = 20,parse = T,
label = "x[1] == x[2]") #添加註釋
畫出的結果如下:
我們可以發現,ggplot的繪圖有以下幾個特點:第一,有明確的起始(以ggplot函數開始)與終止(一句語句一幅圖);其二,圖層之間的疊加是靠「+」號實現的,越後面其圖層越高。
其次就是對於分組數據的處理,其實這方面,lattice已經做得很好了,不過我會在後面更仔細地敘述ggplot2是怎麼看分組數據的繪圖的。
2. ggplot2的要素
我們這裡不談qplot(quickly plotting)方法,單純談ggplot方法。不談底層的實現思想,我們簡單地理解,ggplot圖的元素可以主要可以概括如下:最大的是plot(指整張圖,包括background和title),其次是axis(包括stick,text,title和stick)、legend(包括backgroud、text、title)、facet這是第二層次,其中facet可以分為外部strip部分(包括backgroud和text)和內部panel部分(包括backgroud、boder和網格線grid,其中粗的叫grid.major,細的叫grid.minor)。大致見下圖,這部分內容的熟悉程度直接影響到對於theme的掌握,因此希望大家留心。
3. ggplot2圖層以及其他函數的分類
好了,現在把這些理念的東西講完了之後,下面來理解ggplot2里的繪圖命令。
ggplot2里的所有函數可以分為以下幾類:- 用於運算(我們在此不講,如fortify_,mean_等)
- 初始化、展示繪圖等命令(ggplot,plot,print等)
- 按變數組圖(facet_等)
- 真正的繪圖命令(stat_,geom_,annotate),這三類就是實現一個函數一個圖層的核心函數。
- 微調圖型:嚴格意義上說,這一類函數不是再實現圖層,而是在做局部調整。
- scale_:直譯為標尺,這就是與aes內的各種美學(shape、color、fill、alpha)調整有關的函數。
- guides:調整所有的text。
- coord_:調整坐標。
- theme:調整不與數據有關的圖的元素的函數。
4. 繪圖
第一步:初始化。ggplot2風格的繪圖的第一步就是初始化,說白了就是載入數據空間、選擇數據以及選擇默認aes。
p &<- ggplot(data = , aes(x = , y = ))
data就是載入你要畫的數據所在的數據框,指定為你的繪圖環境,載入之後,就可以免去寫大量的$來提取data.frame之中的向量。當然,如果你的數據都是向量,也可不指定,但是要在申明中標註data = NULL,不然就會得到不必要的報錯。
第二個是重頭戲,即aes,是美學(aesthetic)的縮寫。這是在ggplot2初學者眼裡最不能理解的東西,甚至很多老手也會在猶豫,什麼時候要把參數寫在aes里,什麼時候要寫在aes外。我們做一個簡單的,不非常恰當的解釋:任何與數據向量順序相關,需要逐個指定的參數都必須寫在aes里。這之後我們會進一步解釋,現在我們初始化的時候,最好只是把關於位置的x和y指定一下就好。
第二部,繪製圖層。
很多人在解釋ggplot2的時候喜歡說,ggplot2繪圖有兩種函數,一類是geom_,繪圖用的;一類是stat_,統計變換用的。這樣說不是不對,只是很不恰當,很多人就會問出一些問題,比如,統計變換竟然是做運算用的,為什麼可以用來畫圖?為什麼stat_bin和geom_histgram畫出來的圖是一樣,竟然一樣,為什麼要重複?
事實上,任何一個ggplot2圖層都包括stat和geom倆部分,或者說兩個步驟(其實還包括position)。 而stat_identity則表示不做任何的統計變換。
我們來舉個例子,還是上面的代碼,為了更直觀,我在此作了修改:
x &<- c(rnorm(100,14,5),rep(20,20))
y &<- c(rnorm(100,14,5) + rnorm(100,0,1),rep(20,20))
ggplot(data= NULL, aes(x = x, y = y)) + #開始繪圖
geom_point(color = "darkred")
做出的圖如下:
我們查看碼源,就知道geom_point的默認stat是identity,即不做任何統計變換:
&> geom_point
function (mapping = NULL, data = NULL, stat = "identity", position = "identity",
na.rm = FALSE, ...)
{
GeomPoint$new(mapping = mapping, data = data, stat = stat,
position = position, na.rm = na.rm, ...)
}
&
大家可以發現,我在(20,20)這個點的數據事實上是有20個的,但由於沒做統計轉換(20,20)這個點被畫了20次,因此我們理論上看到的點其實是最後一次畫的那個點。可能這不夠直觀,沒關係,我們調整一下透明度到10%:
ggplot(data= NULL, aes(x = x, y = y)) + #開始繪圖
geom_point(color = "darkred",alpha = 0.1)
得到如下圖:
這樣應該就很明顯了,由於(20,20)點被畫了20次,所以透明度會疊加為20*10% = 200%實際只展現100%。
我們現在就使用坐標轉換來重新畫這個圖:
ggplot(data= NULL, aes(x = x, y = y)) + #開始繪圖
geom_point(color = "darkred",stat = "sum")
好了,解釋一下,stat_sum實際的意思就是按照某一點占所有點出現頻率然後換算成大小來作圖,因此,以上代碼就可以得到下面這張圖,因為(20,20)這個點出現頻率為20/120=16.667%:
好了,我們可以發現了,一個單純的geom_point裡面也是帶有stat_的,因此,其實geom_和stat_實際上是一回事。可能你會問了,那照我的說法,以上這幅圖用的是geom_point里的一個參數,而不是再用stat_sum,這是一回事嗎?bingo!這個問題相當好,的確,按照以上的推理,應該存在一種以stat_sum作為主函數的方法來繪製這幅圖,搞不好,裡面還有個參數geom,要設置成「point」。我們來實踐一下吧:
ggplot(data= NULL, aes(x = x, y = y)) + #開始繪圖
stat_sum(color = "darkred",geom = "point")
尼瑪,還真可以,還長得一模一樣。
現在就講通了,對於有過經驗的同學現在應該重新修正這個觀點——stat_和geom_是兩種繪圖方法。這是錯的,其實它們是ggplot2每一個圖層繪製都必須有的,是一個圖層的一體兩面。
在這一步之中,我們也要回到我們在第一步時出現的問題,aes到底是什麼?為什麼說任何與數據向量順序相關,需要逐個指定的參數都必須寫在aes里?什麼時候color、shape、size、fill寫外面,什麼時候寫裡面?
aes實際上做的是將aes里的向量的順序逐個地繪製。譬如以下代碼(轉自geom_point幫助文檔中的實例):
p &<- ggplot(mtcars, aes(wt, mpg)) #&<---- code 1
p + geom_point(aes(colour = qsec)) #&<---- code 2
結果是:
我們來分析一下ggplot2是怎麼作圖的。首先,我們來看一下mtcars這個數據集長什麼樣:
&> head(mtcars)
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
code 1: ggplot首先載入了這個mtcars的集合,然後指定給了mpg作為其x坐標位置,wt為y坐標位置。
code 2: 指定了qsec作為其染色的標準(分組),qsec為numeric變數,因此,應該選擇連續型的標尺,而不是分組染色。然後開始繪製,讀取mtcars$mpg[1]、mtcars$wt[1],確定位置,然後為其染成mtcars$qsec[1]顏色;再繪製第二點。。。
因此,aes里的美學特徵其實就是按照向量順序指定每個位置的美學特徵,大家可以比較tapply函數的寫法。
好了,現在問題就來了。我想為所有點的顏色都染成綠色,怎麼辦?其實很簡單,如果不需要指定這麼一個染色的順序,而選擇將整個圖層染成一種顏色,則只需要將color寫在aes外:
p + geom_point(color = "green")
哦,怪不得寫在aes里染出來的顏色不是綠色,但為什麼寫到裡面就不可以了,為了寫到裡面,然出來的是粉色?
好了,我們再來分析一下把color = "green"寫到了aes里,到底發生了什麼。
p + geom_point(aes(colour = "green"))
首先,數據的初始化跟上面那個例子是相同的。然後,因為color放到了aes里,於是ggplot開始搜索mtcars裡面的向量了,發現沒有叫"green"的,然後又找了global,也沒有。於是,ggplot就開始把它認作了一個新的向量。等等,有個問題,我要按照這個向量來分別染色,而事實上,這個向量長度為1,怎麼辦?ggplot就先把他展開成了factor(rep("green",nrow(mtcars)),levels = unique("green")),bingo!現在開始染色了。啊第一個數據mtcars$mpg[1]、mtcars$wt[1],其顏色變數是"green",因子水平是1,染成默認調色第一種,哦,就是這個蛋蛋的粉紅色;再染第二個,還是"green",因子水平也是1,染成蛋蛋的粉紅色;... 終於完成了,咦?怎麼都是蛋蛋的粉紅色。
通過舉了這個染色的例子大家應該都弄懂了,aes到底在幹什麼了。其他的美學特徵其實也是完全一致的。只是需要解釋group=1的意思就是說不做分組來進行繪圖。什麼?還是搞不清該放aes裡面還是外面?那就記著想統一整個圖層時就放到aes外,想分成不同組調整,並且已經有一個與x、y長度一致的分組變數了,那就放到aes里。
在這一步里,還要要說的就是我們要講的是ggplot2大致內置了哪些圖:- 點(point, text):往往只有x、y指定位置,有shape但沒有fill
- 線(line,vline,abline,hline,stat_function等):一般是基於函數來處理位置
- 射(segment):特徵是指定位置有xend和yend,表示射線方向
- 面(tile, rect):這類一般有xmax,xmin,ymax,ymin指定位置
- 棒(boxplot,bin,bar,histogram):往往是二維或一維變數,具有width屬性
- 帶(ribbon,smooth):透明是特徵是透明的fill
- 補:包括rug圖,誤差棒(errorbar,errorbarh)
然後,就是按照你的需要一步步加圖層了(使用「+」)。
第三部,加註釋。所有注釋的實現都是通過annotate函數實現的,其實annotate就是一個最簡單的geom_單元,它一次只添加一個位置上的圖形(可以通過設置向量來實現同時繪製多個圖形,但這個理念和注釋的理念有所偏差)。annotate的geom就是指定注釋的類型,其屬性按照geom的不同而發生變化。
第四步,調整。這裡的調整主要是使用微調圖形這大類的函數做美學特徵、坐標軸、標題、繪圖主題的調整。這部分也就是繼承了命令式作圖的思想,使ggplot2的靈活性增加。
如何搜索你要用什麼美學特徵調整函數,其實就是按照美學特徵的名字來,例如,你要調整的是fill,就找scale_fill_之後就有一些不同的染色方法(關於色彩,如果有時間還會添加相關知識);調整的是橫坐標標尺,就找scale_x_然後後面跟上你的橫坐標類型;其他雷同。
在調整主題這方面,值得褒獎的是,theme函數其實最妙的地方是將對於數據相關的美學調整和與數據無關的美學調整分離了。譬如說,我們要改變x軸的顏色,或者panel的底色,這個其實與數據處理無關,這種分離就會使得我們可以如此流程化地操作作圖,而不需要在考慮數據的時候還要關注到與數據無關的美學參數。有人有時候會覺得ggplot2很奇怪的地方就是為什麼調整legend的時候,有時要用scale_,有時又要用theme,其實這都是對於ggplot2這個設計理念的不理解,作者的設計思路是要將數據處理與數據美學分開,數據美學與數據無關的調整分開。
其次,theme函數採用了四個簡單地函數來調整所有的主題特徵:element_text調整字體,element_line調整主題內的所有線,element_rect調整所有的塊,element_blank清空。這種設計相當地棒。
ggplot(data = , aes(x = , y = )) +
geom_XXX(...) + ... + stat_XXX(...) + ... +
annotate(...) + ... +
scale_XXX(...) + coord_XXX(...) + guides(...) + theme(...)
5. ggplot2的一些缺點
- 公式支持不好,自帶的plotmath公式無法滿足很多需求
- 無法針對多個legends進行調整
- 效率不高,繪圖速度較慢,這也表示二次開發的可能性不高
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
以上是使用的心得,希望對大家有用。主要是在理念上解釋一些容易產生困惑的問題。在這裡提了一個自問自答的問題來推廣一種十分優雅的數據可視化工具,R的ggplot2包。其實我自己現在主要在使用Python和Pandas和Numpy工作,ggplot2應該是我留守在R裡面最大的理由之一~
在介紹ggplot2之前,我首先來介紹一下作者Hadley Wickham。Hadley (Rice University Department of Statistics : Faculty)從統計學名校Iowa State University拿到了自己的Ph. D,其博士論文Practical tools for exploring data and models 就是關於數據可視化和探索性數據分析的,現任Rice University的Adjunct Assistant Professor 和R的著名IDE RStudio的首席科學家。Hadley在R語言用戶中具有極高的聲望。R的基礎版本其實是不太好用的,但是Hadley的一系列優秀作品極大地改進了R語言。今年五月在北京召開的R語言會議,好多人都爭相和Hadley合影,可見Hadley的魅力與聲望非同一般。Hadley開發一個package的時候會先開發一個版本,如果他覺得不夠好又升級了,就會發一個新版本,名字變成舊名字後面加上數字2。所以我們就有了reshape2和ggplot2。
ggplot2基於Leland Wilkinson在Grammar of Graphics(圖形的語法)中提出的理論,取首字母縮寫再加上plot,於是得名ggplot。按照《圖形的語法》一書中的觀點,一張統計圖形就是從數據到點、線或方塊等幾何對象的顏色、形狀或大小等圖形屬性的一個映射,其中還可能包含對數據進行統計變換(如求均值或方差),最後將這個映射繪製在一定的坐標系中就得到了我們需要的圖形。圖中可能還有分面,就是生成關於數據的不同子集的圖形。使用ggplot2繪圖的過程就是選擇合適的幾何對象、圖形屬性和統計變換來充分暴露數據中所含有的信息的過程。ggplot2需要一定的時間去入門學習,但是當你掌握了ggplot2中圖形的語法的時候,我相信你會感受到這套語法的優雅。
在接下來的部分,我假定讀者已經對R語言有了基本的了解,我將不會介紹DataFrame等基本概念。
安裝ggplot2和安裝其他的R包沒有差別,在R的console裡面運行install.packages("ggplot2") 一句就可以了,如果你使用RStudio,也可以在Package列表那裡用滑鼠去安裝。
先來介紹一些ggplot2中的基本概念,括弧裡面對應的是ggplot2中為這種屬性賦值的時候需要使用的參數名
圖形屬性(aes) 橫縱坐標、點的大小、顏色,填充色等
幾何對象(geom_) 上面指定的圖形屬性需要呈現在一定的幾何對象上才能被我們看到,這些承載圖形屬性的對象可能是點,可能是線,可能是bar
統計變換 (stat_) 比如求均值,求方差等,當我們需要展示出某個變數的某種統計特徵的時候,需要用到統計變換
我們來看下面這張圖
這張圖裡面用到的圖形屬性是,橫坐標x,縱坐標y,點的顏色,使用的幾何對象是點,沒有進行統計變換
下面這張圖使用的圖形屬性是橫坐標x,使用的幾何對象是bar,使用的統計變換是封箱(bin),也就是分一點間距計數。 大家都知道,這張圖其實就是直方圖(histogram)。這種傳統的統計圖形也都是可以被容納在ggplot2的圖形語法框架之內的,當你熟練掌握ggplot2之後,可以根據圖形語法自己構建新的統計圖形。
ggplot2對於ggplot()函數生成的ggplot對象重載了+這個運算符號,我們可以從一個不含有任何內容而只是指定了數據的ggplot2圖形開始,逐步添加新的元素,最終得到一張內容豐富的圖形。
假設我們這裡已經有了一個名為mtcars的資料庫,其中有兩列wt和mpg
p &<- ggplot(mtcars)+aes(x=wt,y=mpg)
我們首先指定要用mtcars這個dataframe來繪圖,然後我們又指定了圖中的橫縱坐標分別表示什麼,現在圖上還是看不到東西的,只能看到坐標軸,我們要繼續指定幾何對象。p + geom_point()
這樣我們就得到了一張最基本的散點圖。
我們還可以按照另外一個變數對點上色
p + geom_point(aes(colour = qsec))
這裡使用的qsec是一個連續變數,我們還可以指定一個因子
p + geom_point(aes(colour = factor(cyl)))
這樣就生成了我們之前的那個例子
先寫到這裡 之後再慢慢更新吧
推薦兩本書一本是Hadley自己寫的
ggplot2: Elegant Graphics for Data Analysis
另一本是 R Graphics Cookbook
目前國內都有出版,我覺得都很不錯
(已更新至第五節,謝謝關注!)
一.使用示例
1.1 基本繪圖
(上圖參考了ggplot2_The_Elements_for_Elegant_Data_Visulization_in_R這本書,結合了library(gridExtra)中的grid.arrange()函數整合到一幅圖中。看起來有沒有小清新的感覺?(●"?"●)
)
1.2 拓展應用示例1——地圖繪製
(上面兩幅圖由ggmap包繪製,該包結合了ggplot2和maps的長處,非常強大。第一幅我畫的,第二幅《中國地震數據可視化》由肖凱老師實現,結合animaiton包實現了動態呈現,見博客http://xccds1977.blogspot.jp/2012/06/ggmap.html。差距啊( ╯□╰ ))
1.3 拓展應用示例2——主流媒體主題
沒接觸R以前,曾經在圖書館看到別人推薦的《Excel圖表之道》這本書,裡面告訴讀者如何設計和製作達到雜誌級質量的、專業有效的商務圖表。各種紛繁複雜的excel技巧讓我眼花繚亂而嘆為觀止。只可惜,excel學起來總感覺效率低下,學了就忘,並且可重用性差,最終它在我的書桌上安靜地躺了兩個月,又被無奈的還回去了。終於有一天,我看到ggthemes這個基於ggplot2的拓展包,我感覺我的人生又充滿了希望。我們來亮兩張圖,後面會有相應的詳細介紹。
(其實只要在ggplot2的代碼上額外加一行代碼即可實現。有沒有瞬間高大上的感覺?)二. 語法直觀認識
- 一個圖形對象就是一個包含數據,映射,圖層,標度,坐標和分面的列表,外加組件options。
- 每一個元素都是一個對象,可通過重載的『+』疊加。這個特點的神奇之處,在於我們可以非常方便的逐步調整和修飾我們的圖形。來個示例代碼感受一下:
scatter&<-ggplot(mtcars, aes(x = wt, y = mpg, color = as.factor(cyl), shape = as.factor(cyl)))+
geom_point()+
geom_smooth(method = lm, se = FALSE, fullrange = TRUE)+
labs(title="Miles per gallon
according to the weight",
x="Weight (lb/1000)", y = "Miles/(US) gallon")+
theme_classic()+
scale_color_brewer(palette = "Accent")+
theme_minimal()
以上的命令生成了示例中的散點圖。其中,每一個「+」前面的部分都是獨立的。也就是說我們可以把變數保存以待下次載入時繼續修改或者讓你的同事來修改、使用。
- 分面和圖層將原數據切割稱多個小數據集,即每個圖層的每個分面面板都含有一個小數據集。你可以把它想像成一個三維矩陣:分面面板形成了一個2維網格,圖層在第三維的方向上疊加。分面這個概念使得分組對比圖的繪製非常方便。而圖層的概念使得我們用R繪圖跟藝術家繪圖別無二致。如gglot()函數如同開啟了一塊畫布,通過「+」疊加的幾何對象:簡稱geom,控制生成的圖像類型,如geom_line(),geom_point(),可以進行圖層的疊加,也就相當於是層層繪製,把同一來源的數據通過不同的圖形類型展示在同一幅圖中,或者把不同來源的數據很方便的展示在同一個圖形對象中。也可以理解成每一塊畫布是透明的,通過畫布的疊加來豐富我們的圖形對象。
- ggplot2繪圖過程解析(見ggplot2-數據分析與圖形藝術P37) 。
繪圖過程需要瞭然於胸,才能避免犯錯。其中涉及到的一些概念後續會有介紹。
三. 優勢——為什麼不用plot
我們前面絮絮叨叨的說了這麼多概念語法之類的玄之又玄的話題,有的同學肯定要問了:「我為什麼要去接受這些高深莫測的新概念,繪圖直接一個plot不就完事兒了嗎?」
0.ggplot2的默認設置已經可以使你的圖形很精美,精美到甩plot幾條大街。
1.基礎繪圖系統中的plot()函數雖然已經很強大,但是還不夠便利。因此,ggplot2有了模仿plot()設計的qplot()函數。
2.基礎繪圖系統中,有兩類繪圖函數,低級函數和高級繪圖函數。高級繪圖函數繪製的是一個完整的繪圖函數,低級繪圖函數在已有的圖形對象中進行添加,相當於ggplot2中的圖層疊加概念,但是肯定沒有ggplot2的圖層概念強大。假設你要用plot繪製一個類似分面的圖形,那麼你可能需要n個可重複的步驟,然後通過par()中的mfrow參數來整合到一塊兒。
3.函數和參數設置方便記憶。這一點非常重要。你不需要像SAS繪圖系統那樣牢記幾十上百個參數就可以繪製比SAS繪圖系統更漂亮的圖形(我也不知道為什麼突然跑題去黑SAS了( ╯□╰ ))。在R繪圖設備中,每一個不同的圖都有一個獨特的函數比如boxplot(),hist(),barplot()等;然而在qplot()函數中,用geom參數取不同的值即可畫不同的圖,而geom_+圖形對象名即可繪製不同的圖。結合Rstudio開發環境下的參數提示、函數提示和自動補全功能,再也不用擔心複雜的參數和函數記憶問題了。
4.我覺得最重要的是,ggplot的代碼可重用性更強,可以很方便地定製化一些帶有你自己特色的圖形。如果你是上班族,每隔一段時間就需要做一些重複性的數據分析工作,那麼這個特點對你幫助更明顯。
四. 快速入門——qplot
qplot(),是quick plot 的縮寫,顧名思義,就是讓你快速的繪製一幅圖。Hadley建議我們,如果想學好R中的函數封裝,應該認真閱讀qplot的源碼,理解它的工作機理。可見,這個函數是非常值得學習的。代碼長度不到100行,但我目前還沒完全看懂( ╯□╰ )。
先來看一下qplot()的參數。
qplot(x, y = NULL, ..., data, facets = NULL, margins = FALSE,
geom = "auto", stat = list(NULL), position = list(NULL), xlim = c(NA,
NA), ylim = c(NA, NA), log = "", main = NULL,
xlab = deparse(substitute(x)), ylab = deparse(substitute(y)), asp = NA)
這個函數從參數個數來看,可謂是,麻雀雖小,五臟俱全。
來個例子。
```{r}
#lm regression
qplot(mpg, wt, data = mtcars, geom = c("point", "smooth"),
method = "lm")
```
要在基礎繪圖中實現這個圖形,需要至少兩步,而這裡只需要一步。再看一個例子。
```{r}
qplot(cty,hwy,data = mpg)+facet_grid(.~cyl)
```
這個圖,用基礎繪圖可能就不是一步兩步就能搞定了。我推薦的幾本書都有很多的使用示例,這裡就不多贅述了。總之一句話:如果你想快速的看看數據的形態,qplot應該是你的首選。
五. 繪圖流程——讓思路更清晰、圖形更優雅
5.1 數據準備
說到數據準備,就不得不提同為Hadley開發兩個專用於數據清洗的包:dplyr和reshape2.這兩個包也可以說是為ggplot2而生。三者結合起來,簡直妙不可言。代碼可以寫得非常優雅,圖形也會更有表現力。他們都是基於data.frame的數據結構之上。
5.1.1 dplyr的理念介紹和示例
- 時間是寶貴的。關鍵的部分由Rcpp寫成。
- 本地能做,遠程也理應能做。遠程資料庫介面支持: PostgreSQL, MySQL, SQLite 。
- 每個函數只做一件事,並把它做好。group_by,summarise,mutate,filter,select,arrange等等這些函數組合起來,幾乎可以勝任所有日常的數據清洗工作.
- 另外,我覺得最重要的是管道操作的功能。操作符『%&>%』可以把前一步處理的結果當作第一個參數傳給下一個處理函數。這個操作讓你的代碼更具有可讀性,處理數據的思路過程也更清晰。
理念介紹參考&
```{r}
library(dplyr)
library(nycflights13)
flights %&>%
group_by(year, month, day) %&>%
select(arr_delay, dep_delay) %&>%
summarise(
arr = mean(arr_delay, na.rm = TRUE),
dep = mean(dep_delay, na.rm = TRUE)
) %&>%
filter(arr &> 30 | dep &> 30)
```
操作介紹可以參考&
由於這裡的主角是ggplot2,其它的一些使用細節就不多談了,詳細使用請參考給出的鏈接。
5.1.2 reshape2與ggplot2結合的示例:anscombe數據集可視化。
如果接觸過資料庫的同學,對「長表」和「寬表」應該有所理解。而reshape2就是用於這二者的轉換。reshape2目前我只用過兩個函數:melt()和dcast().這兩個函數用來「糅數據」簡直無敵。隨便你怎麼在寬表和窄表之間轉換。詳細使用可以參考&
這裡舉一個我實現的非常有意思的例子。
(後續添加anscombe數據集的介紹。)
```{r}
library(dplyr)
library(reshape2)
library(ggplot2)
View(anscombe)
anscombe.new&<-mutate(anscombe, n = seq(1:nrow(anscombe)))
str(anscombe.new)
#melt
narrow.data&<-melt(anscombe.new, id.vars = ("n"))
head(narrow.data)
narrow.data2&<-mutate(narrow.data,
group = substr(variable,2,2),
variable = substr(variable,1,1))
#dcast
narrow.data2&<-dcast(narrow.data2, n + group~variable)
View(narrow.data2)
#plot
ggplot(narrow.data2, aes(x = x, y = y, colour = group))+
geom_point()+
geom_smooth(method = "lm")+
facet_grid(.~group)
```
可以得到如下的圖。
5.2 創建圖形對象
如下所示,用ggplot()函數創建一個圖形對象。```{r}
library(ggplot2)
p&<-ggplot(data = diamonds, aes(x = carat, y = price, colour = cut))
```
參數映射,只需要把需要映射到圖形屬性的變數名放到aes()函數內即可。
5.3 添加圖層
可以使用layer()函數添加圖層。如繪製以carat為x軸,price為y軸的散點圖。```{r}
p1&<-p+layer(geom = "point")
```
對於每一個圖層,我們只需要設定stat或者geom參數即可。這是因為每一個幾何對象都對應一個默認的統計變換和位置參數,而每一個統計變換都對應著一個默認的幾何參數對象。
```{r}
p2&<-p+layer(stat = "identity")
```
也可以使用快捷函數來簡化以上代碼。
```{r}
p3&<-p+geom_point()
```
以上三種方式都可以生成同一幅圖形。
5.4 數據
ggplot2需要傳入一個data.frame格式的數據。數據的前期準備前面已有介紹。而數據在圖形圖像中是以副本的方式保存的,這說明我們可以保存圖形對象(ggsave())以待下次載入(load())。
5.5 圖形屬性映射aes()
aes()用來將數據變數映射到圖形中。
如aes(x ,y,colour=z);
又如aes(x,y,group = z)——將數據分成若干組,並用相同的方式對每個組進行渲染。值得一提的是,當現有的單個變數不能夠正確的分組而兩個變數的組合可以正確分組時,可以使用interaction()函數進行分組。
5.6 幾何對象
幾何對象:簡稱geom,控制生成的圖像類型,如geom_line(),geom_point(),geom_bar().
5.7 統計變換
統計變換:stat。它通常以某種方式對數據信息進行匯總。ggplot2中包含的統計變換有如下多種。統計變換可以向原數據集中插入新的變數。示例。如
```{r}
#geom
hist1&<-ggplot(diamonds, aes(carat))+
geom_histogram(aes(y = ..density..),binwidth = 0.1)
#或者stat
hist2&<-ggplot(diamonds,aes(carat))+
layer(stat = "bin", binwidth = 0.1)
```
以上統計變換生成了一些新的變數count,density,x。我們可以在aes()中調用這些變數。
5.8 位置調整
置調整一般多見於處理離散性數據。如條形圖中的:堆疊(stack),填充(fill),並列(dodge)。此外,還有jitter:給點添加擾動避免重合;identity:不做任何調整。
如下所示:
```{r}
library(ggplot2)
library(gridExtra)
hist1&<-ggplot(data = diamonds, aes(x = clarity, fill = cut))+
geom_histogram(position = "dodge")
hist2&<-ggplot(data = diamonds, aes(x = clarity, fill = cut))+
geom_histogram(position = "fill")
hist3&<-ggplot(data = diamonds, aes(x = clarity, fill = cut))+
geom_histogram(position = "stack")
grid.arrange(hist1,hist2,hist3, ncol = 3, nrow = 1)
```
5.9 對象整合
5.9.1 幾何對象+統計變換.示例:直方圖的幾種變體.
```{r}
d&<-ggplot(data = diamonds, aes(x = carat))
d1&<-d+
stat_bin(aes(ymax = ..count..), binwidth = 0.1,geom = "area")
d2&<-d+
stat_bin(aes(size = ..density..),binwidth = 0.1, geom = "point",position = "identity")
grid.arrange(d1, d2, ncol = 2, nrow = 1)
```
5.9.2 將不同來源的數據畫在同一張圖
舉例:用模型擬合出來的預測值來擴充原數據集;
```{r}
#例子來源於stackoverflow
df1&<-data.frame(x=1:10,y=rnorm(10))
df2&<-data.frame(x=1:10,y=rnorm(10))
ggplot(df1,aes(x,y))+geom_line(aes(color="First line"))+
geom_line(data=df2,aes(color="Second line"))+
labs(color="Legend text")
```
六. 調整策略——讓圖形更有表現力
七. 深度加工——專業化主題定製
八. Next Generation——ggvis
ggvis介紹: &
- 三本書:
-
- ggplot2-數據分析與圖形藝術
- ggplot2_The_Elements_for_Elegant_Data_Visulization_in_R
- R可視化核心手冊?
- 兩個博客系列地址:
-
- 可視化 (數據鋪子的小站)
- xccds1977.blogspot.jp 的頁面
- 一篇cheatsheet總結(給出鏈接)
-
- ggplot2-cheatsheet
- Beautiful plotting in R_ A ggplot2 cheatsheet _ Technical Tidbits From Spatial Analysis Data Science
ggplot2背後有一系列重要的思想,即圖形的語法(Wilkinson, 2005)。正是這種思想,使得初次接觸者往往一頭霧水,也使得重度使用者對其讚不絕口。在使用ggplot2之間,對這些基本思想有初步了解是有必要的。
- 以「信息」的表達為核心。作圖就是將你從數據(data)中探索的信息與圖形要素(graph)對應起來的過程(mapping)。從數據信息到像素和顏色的轉換過程,在ggplot2中,被稱為「標度變換」(scaling)。如果一個圖中充斥著大量沒有表達信息的圖形內容,那麼這是十分荒唐的。我們見多了那些花里胡哨卻只表達了一個百分比的圖。例如,那種用多個色彩表達出來的「爆裂」式餅圖,其中利用了色彩、面積、位置等複雜的圖形內容,但只表達了簡單的百分比。這隻會讓信息接受者的注意力從信息本身移開,甚至受到誤導。因此,我們首先要牢記的是,信息的表達是目標,各種圖形形式只是為其服務的工具。不能讓工具干擾了甚至淹沒了目標。因此,如果你的目標是做出更「炫」的或更好看的圖形,ggplot2可能並不是你的最佳選擇。如果你的目標是迅速而方便地探索數據中包括的信息,那麼ggplot2可以是你的菜。
- 結構化思維方式。試想一個作圖過程的結構步驟:我們首先決定探索一下身高與體重之間的關係;然後畫了一個簡單的散點圖;然後決定最好區分性別,圖中點的色彩對應於不同的性別;然後決定最好區分地區,拆成東中西三幅小圖;最後決定加入回歸直線,直觀地看出趨勢。這是一個層層推進的結構過程,在更一個推進中,都有額外的信息被加入進來。因此,作圖的命令也最好能夠直觀地反映出我們思維中的這種結構,反映出這種額外信息的不斷加入。只要在原來的命令上作一個小更新,就可以生成加入了新信息的新圖形來。這樣,命令與思維就是完全吻合的。如果不採用一種結構化的思維方式,例如,一般的散點圖與區分性別的散點圖需要用非常不同的命令寫出,那麼這就會打亂思維者的思維過程。這裡重視的是信息的不斷加入,形式的變化應當服從於信息的加入,而不能打擾到信息的加入。另一方面,同樣的信息最好用幾乎同樣的命令表達出來。例如,一個條形圖與一個餅圖的信息是幾乎一樣的,那麼做出一個條形圖的命令只需要加入一個小改動,就應當變成餅圖。
- 基本圖形要素的自由組合。如前所述,作圖就是數據信息與圖形要素對應起來的過程。那麼在這一過程中,我們用來表達信息的基本圖形要素有哪些呢?ggplot2將基本圖形要素分為不同的幾何對象((geom)、不同的幾何對象屬性(aes)、不同的子窗口(facet)等。我們的作圖過程,就是將自己所需要表達的信息對應於上述各種圖形工具。上述圖形工具應當可以進行自由的組合,來用於表達複雜多變的信息。我們可以在散點圖上加上條形圖,然後再區分性別,然後再用子窗口區分地區,等等。如果可以進行這樣自由的組合,研究者就不必再受限了軟體中提供了幾種有限的選擇,而可以根據自己表達信息的需要,用這些基本圖形要素來創造出無窮多種的新圖形來。這些新圖形中是散點圖上又加入了線圖,同時又有性別、地區的信息等等,這些複雜的圖形往往沒有特定的名字。這種自由組合無疑給了研究者巨大的自由發揮空間。
ggplot2中的基本圖形要素包括:
- 不同的幾何對象(geometric object,簡稱geom),如用點(線、形)來表示身高與體系的兩維點。在ggplot2中,共有30多種幾何對象。
- 這些幾何對象的屬性(attributes,簡稱aes),如幾何對象是點,但可以有不同的顏色(大小或形狀),來表示兩種性別。一般,顏色與形狀適合表示分類變數,大小適合表示連續變數。對散點圖而言,每個點最基本的屬性即其橫坐標與縱坐標
- 不同的子窗口(facet)。如可以將幾何對象繪於三個子窗口中,來比較東中西地區。
- 統計變換(statistical transformation, 簡稱stats)。如在圖中加入一條回歸線,這是將我們看到的數據關係用一個統計線性關係來表示。
- 坐標系(cooridnate system, 簡稱coord)。
學習ggplot2,入手的捷徑命令是qplot。qplot是與傳統的作圖命令非常接近的命令,但加入了一些ggplot2的一些結構化思維要素,可以作為初學者很好的過度。
## 首先了解幾何對象geom
## 在下圖的例子中,我們用幾何對象「點」來表示兩個變數間的關係,這是最常見的情況(默認情況,即geom="point")。
qplot(carat, price, data=diamonds)
qplot(log(carat), log(price), data=diamonds)
qplot(carat, x*y*z, data=diamonds)
## 我們也可以加入另外的幾何對象(平滑曲線)來表示更多信息。
qplot(carat, price, data=diamonds, geom = c ("point","smooth"))
qplot(carat, price, data=diamonds, geom = c ("point","smooth"), method = "lm")
## 加入平滑曲線的方式可以進行控制,詳情參見其幫助文件。
## 可以使用其他的幾何對象
qplot(color, price / carat, data=diamonds, geom = "boxplot" )
qplot(carat, data=diamonds, geom = "histogram" )
qplot(carat, data=diamonds, geom = "density" )
## 離散變數多用條形圖
qplot(color, data=diamonds, geom = "bar" )
## 時間序列多用線圖和路徑圖
qplot(date, unemploy / pop, data = economics, geom = "line" )
qplot(date, uempmed / pop, data = economics, geom = "line" )
####幾何對象的屬性aes
## 小數據集
set.seed(1410)
dsmall &<- diamonds[sample(nrow(diamonds),100),]
##下面加入幾何對象的屬性(顏色與形狀來表示額外的信息)
qplot(carat, price, data=dsmall, colour=color)
qplot(carat, price, data=dsmall, shape=cut)
qplot(carat, data=diamonds, geom = "density" , colour = color)
qplot(carat, data=diamonds, geom = "histogram" , fill = color)
#### 子窗口facet
#### 把幾何對象置於不同的子窗口中進行比較,這些子窗口被稱為facet。與用幾何對象的屬性來表達信息相比,用子窗口來表達信息既有優勢,也有劣勢,這要取決於所要表達的信息內容特點及其應用情境。
qplot(carat, data= diamonds, facets = color ~ . , geom = "histogram")
當然,還可以加入標題(命令為xlab,ylab,main)與坐標軸(xlim, ylim, log)。
要更靈活地操縱幾何圖形與圖形屬性,要實現「基本圖形要素的自由組合」,更理想的工具就是ggplot2了。這裡的一個思路是「+」,用「 +」把各種基本圖形要素象搭積木一樣搭出來。先寫數據集,再確定圖形屬形中的橫縱坐標,然後一步一步地加入各種自己想要的圖形要素。
## 先設定默認的數據與默認的圖形屬性映射(屬性為點的x軸和y軸坐標位置)
p &<- ggplot ( dsmall ) + aes ( carat , price ) )
## 開始填加幾何對象
p+ geom_point()
p+ geom_point() +geom_smooth()
## 開始填加幾何對象的屬性(顏色來表示信息)
p+ geom_point(aes(colour=color) )
p+ geom_point(aes(colour=cut) )
p+ geom_text(aes(label=color))
## 改變一下y軸表示的信息
p+ geom_point ( aes ( y = log ( price) ) )
## 分組的線圖
p &<- ggplot(Oxboys, aes(age,height, group= Subject)) + geom_line()
p
p + geom_smooth(aes(group=1), method = "lm", size = 2, se=F)
使用ggplot2還可以更靈活地使用多個數據集,如下面的例子。
## 更改一個數據作圖,只需要%+%
p &<- ggplot(dsmall, aes(carat, price))+ geom_point()
p %+% diamonds
當然,也可以方便地加入標題與元數據
## 加上標題(加上labs)
p+labs(title="這是一個圖")
## 標註出價格最高的那個點(再加上一個geom_point)
highest = subset (dsmall , price == max (price))
p + geom_point(data=highest, size=6, colour= "red",alpha=0.5)
還可以變換主題。
## 主題的使用
p + theme_grey()
p + theme_bw()
p + theme_classic()
library("ggthemes")
p + theme_stata()
目測一大波大牛來襲,先佔個坑。談談學習 ggplot2的小體會。雖然網上有一大堆講ggplot2的好處,但是我最先體會也是最直接的體會就是 ggplot2划出的圖簡潔漂亮,就是這麼簡單粗暴。還有就是facet 很好用,可以分析多變數。用多了,ggplot2的好處才能慢慢體現出來。紙上得來終覺淺,絕知此事要躬行。
我有Hadley依賴症,他的dplyr,plyr,stringr,ggplot2都很犀利,簡潔快速,讓人用起來欲罷不能。Hadley 寫的《ggplot2 數據分析與圖形藝術》,這本書其實就講了一句話:A statistical graphic
is a mapping from data to
aesthetic attributes (colour,
shape, size) of geometric
objects (points, lines, bars) .
後面的章節就是圍繞這句話展開的。吐槽一下中文版的這本《ggplot2 數據分析與圖形藝術》,估計是我人品太差,買回來沒幾天塑封就破了。還有就是ggplot2現在已經1.0.0了,中文版的用的好像是0.92版的(時間長了忘記了),正式版測試版還是有很多地方不一樣的。Hadley博客里聲稱要更新一下這本書,不過不知道要到猴年馬月了。
《R語言數據可視化手冊》這本書,是彩印印刷的,雖然貴了點,但是看起來很直觀,很方便不需要對照電子版的看了。作者Winston Chang也是Rstudio公司的,Hadley的同事,ggplot2的公共開發者,所以這本書也非常棒。而且作為一本cookbook,需要時候翻一下,還是非常方便的,電子版的書查找起來還是不方便。就是有一個遺憾,裡面的數據是用plyr包整理的,而不是dplyr包,少了一次實戰學習dplyr包的機會。不過也很合理,dplyr包14年1月份才放出來。
Hadley是崇拜的大神,統計之都有關於他的採訪,很值得一讀。 他當初也是准本學醫的哦,激勵著我好好碼代碼,做一個非主流的醫學生。
QiuYixuan: COS訪談第九期:Hadley Wickhamplotly 的配合可以讓 D3.js 作為 ggplot2 的繪圖引擎,從而讓 ggplot2 具備互動式能力,具體可以參考 ggplot2 | plotly,這個功能賦予 ggplot2 更強大的數據分析能力,也提供了更多的產品化的可能性。這個用熟後,可以把 rCharts 一眾打入冷宮了。
另外最新的 rmarkdown 配合使用 flexdashboard 可以支持布局,因此強烈安利 rmarkdown + flexdashboard + plotly + ggplot2 這一方案。
這個方案配合 Python Flask 等 web framwork,可以作為內部報表和數據分析系統的技術選型。這一選型在開發效率、數據分析和可視化能力方面優勢明顯,缺點是 R 的性能是個瓶頸,因此僅適用於 pv 在 100 萬以下的應用了,再往上就得堆機器了,但內部報表系統往往使用量不會那麼大,所以不用考慮太多。看源文檔是最佳的學習方式,ggplot2是一個完整的框架體系,單列出來都能作為一門語言,如果一開始就是星星點點的百度、知乎搜索著學習,你會走很多彎路,到最後還得回來看源碼,推薦兩本ggplot2的著作:
《R數據可視化手冊》《ggplo2數據分析與圖形藝術》
在線源文檔:
Function reference ? ggplot2
個人專欄:
R語言數據分析與可視化
多總結框架和體系,實戰與理論結合,不要只看不寫,也不要只寫不總結!
如果你想知道ggplot2可以作出什麼水準的圖表,可以看這一篇:
學習R語言我都做了那些有趣的事情!!!
個人也整理了自己R語言學習新的筆記,其中不乏大量ggplot2內容,僅供參考,拿好不謝!
那些年倒騰的R語言學習筆記,全都在這裡了~
本人用R一年多了,花了一個多月的時間鑽研了ggplot2,感覺ggplot2帶給我最深的兩點是:映射和圖層。這是R中其它函數做不到的!
ggplot2與地理大數據結合會更酷(直方圖和散點圖什麼的弱爆了)!
通過不同圖層的疊加,將圖形繪製出來,還可製造出光暈效果。
一切都是模板,一切都是套路。來來,我談下ggplot2里的套路,包學包會,哈哈。
- 第一印象
使用ggplot2繪製圖形比R自帶的繪圖函數方便很多。使用前需要用install安裝包,並用library將包引入程序中
我們看下一張圖裡的代碼繪製了散點圖,可以先大概了解下怎麼用。
有了這個直觀的印象後我們詳細看下面的圖片如何繪製出這樣的圖的。
- 創建畫板
代碼的第一部分是一個ggplot函數,裡面傳入的數據是我們之前得到的航班延誤時間delay數據框。
這個函數的作用是為繪圖創建一個空白的畫板,為後面再畫板上作圖做準備。
只運行ggplot這一行代碼,我們可以看到一個空白的畫板。
- 創建圖層
我們再來看代碼的第2部分,是個geom_point函數,根據函數名稱我們也可以猜出來是在畫板上繪製點。
我們詳細看下這個函數,第1部分是個輸入參數名mapping,第2個部分aes是英文單詞Aesthetic的縮寫。
aes裡面輸入的x值是圖像里的橫坐標,這裡是航行距離。y是縱坐標,這裡是航班到達延誤時間。
Gemo_pint說的更準確是在畫板上加入一個點圖層。如果你用過PS軟體畫圖,就知道最終的圖像是一層一層加上去的。
Ggplot2包是用加號,將每個圖層加到之前創建的畫板。
我們再來為圖形加入一個圖層,用geo_smooth 用ggplot2來為散點圖添加平滑曲線,以方便清楚的看到航行距離與航班延誤時間之間的關係。
我們看到geo_smooth和geom_ponit的使用方法一樣。
- ggpot2的繪圖模板
通過使用ggplot2繪圖我們看到繪圖很方便,只需要知道下面的模板就可以了。
第1部分是創建繪圖的畫板,其中尖括弧里的內容代表繪圖需要的數據框。
第2部分是添加的圖層,可以用加號添加多個圖層。尖括弧里的geom_function代表不同的ggplot2繪圖函數,可以是像之前的繪製散點圖的函數,也可以是繪製柱狀圖的函數。
你肯能會說你只告訴我一個模板,但是很多圖形我還是不會繪製啊。
其實你也不需要知道每個ggplot2的函數或者如何繪圖。你只需要了解現在講的大概繪圖流程,當遇到需要繪製心目中的圖像時,谷歌下就能看到很多現成的答案。有了谷歌,還怕遇到問題嗎?
你會發現我教的都是學習方法,而不是給你講每個函數如何使用,如果不掌握學習方法,即使你把所有的函數都背下來,遇到問題還是不會如何解決。
如果你還不會使用谷歌,在微信公眾號:猴子聊人物,中回復「谷歌」看到我之前寫的詳細方法。
看,一切都是套路,學習方法很重要。
ggplot2算是R中比較難學的包之一了,主要原因在於繪圖思路和基礎包有很大不同,函數又非常多,資料多而雜,很多文章都是想到哪寫到哪,沒有一個清晰的脈絡。
要了解ggplot2包中的函數,我的建議是扒遍官方文檔的函數來學習,看代碼和做出的圖形自然就懂了。我也是這麼走過來的,知道路途遙遠而艱辛,很多參數都沒有在幫助文檔的例子中呈現,還要自己一個個調,一個個試,然後不斷總結調整一個細節應該到哪個函數中設置(淺顯來說,這是ggplot2使用時和基礎函數最大的不同,基礎函數畫一種圖,一個函數,所有參數都在這個函數裡面了,參數可以做的就是所以你可以調節的內容;而ggplot2作一個圖是要調用很多函數來完成的)。
所以說看幫助文檔的話總結是很關鍵的,因為文檔中是一個個函數列出來的,只是你每次學到一個函數時就會感嘆一聲,原來這個是在這個函數中調的呀,這樣看遍文檔你畫圖才能得心應手、信手拈來。
正是因為深感不方便,於是我自己總結了幾篇文章,思路如下
- 先畫一個基礎圖形,對圖形多個位置進行調整,讓讀者大致知道調這些在哪個函數裡面(第一篇)
- 以柱狀圖為例,看這個包可以實現哪些方面的功能(第二篇)
- 對之前提到的功能進行擴展,幾乎覆蓋相關功能的所有函數與所有參數(後面所有)
前兩篇會讓你對柱狀圖有一個比較清晰的了解,後面幾篇全是針對所有類型圖形的通用做法。所以本系列旨在以柱狀圖為例,剖析ggplot2作圖的規律,讀者看完自然就可以觸類旁通到其他類型的圖形中了。
註:本系列文章涉及到非常非常多參數細節的調整,相比於官網只多不少,所以要花費較長時間來學習,但是學完畫圖肯定可以信手拈來了。
文章目錄如下
R|ggplot2(一)|一個完整的繪圖流程
R|ggplot2(二)|覆蓋柱狀圖各種需求
R|ggplot2(三)|coord 系列函數坐標軸轉換
R|ggplot2(四)|stat_ geom_ 和position
R|ggplot2(五)|scale 修改默認設置
R|ggplot2(六)|套用主題模板
R|ggplot2(七)|自定義主題
看了看大家回答,感覺ggplot功能好強大,原理參照熱門回答,下面舉幾個例子來看ggplot2的用法
數據來自AER包中的信用卡信息數據(CreditCard),包括了
例子一:老闆對做數據的阿旺說,阿旺啊,給我看看這次客戶的年齡分布情況
阿旺說,好嘞!
(這個直接用的hist,不是ggplot,因為我覺得一維的用hist更好看一些)
hist(CreditCard$age, breaks=100, main="Histogram of age", xlab="age in years", xlim=c(0,70))
如果你一定要用ggplot那滿足你:
ggplot(data=CreditCard,aes(age))+geom_histogram(bins=20,alpha=0.5,fill="black")
例子二:老闆看到這次顧客的年齡分布圖後,想了想,阿旺啊,給我看看各年齡層收入情況
阿旺說,好嘞!
ggplot(CreditCard, aes(age,income)) +geom_point(stat="identity")
老闆看了看,可以再突出下重點嗎?
阿旺說,好嘞!
p&<- ggplot(CreditCard, aes(age,income)) +geom_point(stat="identity")
p&<- p+stat_smooth()
p
例子三:老闆看了看顧客的年齡+收入分布後,對阿旺說,阿旺啊,大概收入我是知道了,給我看看這些年齡收入下,哪些辦了卡,哪些沒辦卡?
阿旺說,好嘞!
p &<- ggplot(CreditCard, aes(age,income,colour=card)) +geom_point(stat="identity")
p&<- p+stat_smooth()
p
例子四:老闆說,阿旺啊,有些辦了卡但不是卡主人,你幫我看看有多少人?
阿旺說,好嘞!
ggplot(CreditCard,aes(card,fill=factor(owner))) +
geom_histogram(stat = "count")+
labs(x ="是否辦了卡")
老闆說,具體比例是多少呢?
阿旺說,好嘞!
ggplot(CreditCard,aes(card,fill=factor(owner))) +
geom_bar(position="fill")+
labs(x ="是否辦了卡")
例子五
老闆點了點頭,阿旺啊,豎著有點丑,你要不橫著試試?
阿旺說,好嘞!
ggplot(CreditCard,aes(card,fill=factor(owner))) +
geom_bar(position="fill")+coord_flip()+
labs(x ="是否辦了卡")
(橫著的也沒特別好看的說= ...=)
例子六
老闆說,阿旺啊,我想看看有卡的,沒卡的活躍度情況?
阿旺說,好嘞!
ggplot(CreditCard,aes(x=active,fill=card))+geom_bar()+facet_grid(.~card)
例子七
老闆說,阿旺啊,可以看看有卡沒卡的活躍度嗎?對了還有他們的報告次數
阿旺說,好嘞!
ggplot(data=CreditCard,aes(x=age,y=active,col=factor(owner),size=factor(reports)))+geom_point()+labs(size="reports",col="owner")
例子八
老闆說,阿旺啊,可以看看辦卡的和沒辦卡的月份箱線圖嗎?
阿旺說,好嘞。。
q &<- ggplot(data=CreditCard,aes(x=card,y=months))
q+ geom_boxplot(size=1)
聽說新來的做數據的來福會ggtheme包,
這天,
老闆敲開了來福的門
------全劇終----
(故事純屬虛構,如有雷同,那就雷同吧~)
------------------------------------------------------
總結一下,對於ggplot圖,先輸入數據集,再在aes中輸入橫縱軸變數,同時可以設置顏色尺寸,加號後面是圖類型,(換句話說,沒有加號,無法生成圖)
其實tebleau更方便=。。=點兩下就出來了,圖還真性冷淡-風的好看~
不過加了ggtheme包的ggplot的圖顏值還是很高的。(下圖)
愛折騰的還可以去瞄瞄python的seaborn,在matblotlib基礎上的更好看的畫圖工具,圖也超級好看。
以上。
這題我會~
有回答講了理念知識,而且講的很好,我就主要通過例子講ggolot入門操作了。
在開始使用之前,安裝ggplot2:
install.packages("ggplot2") #如果已經安裝了可以忽略這一步
library(ggplot2) #如果已經載入了可以忽略這一步
(我比較喜歡載入tidyverse包,因為裡面比較全,包括:
- ggplot2, for data visualisation.
- dplyr, for data manipulation.
- tidyr, for data tidying.
- readr, for data import.
- purrr, for functional programming.
- tibble, for tibbles, a modern re-imagining of data frames.)
下面就可以開始用了。
一個ggplot的完全形態包含多層:
1. data
2. aesthetics
3. geometries
4. facets
5. statistics
6. coordinates
7. themes
看起來很複雜的樣子,但是不要慌,一般情況下並不需要用到所有這些。一個基本的圖需要前三層:data, aesthetics, geometries。
先畫幾個基本的圖看看~
第一個例子:
ggplot(mpg, aes(cty, hwy)) +
geom_point()
第一行包含了data和aesthetics,寫完整是ggplot(data = mpg, mapping = aes(x = cty, y = hwy))。mpg是ggplot2里自帶的汽車數據集,cty和hwy是裡面的兩個變數,分別代表city miles per gallo和highway miles per gallon。第二行是geometry,告訴ggplot圖的類型,這個例子畫的是散點圖,所以是point。兩層之間用「+」連接。
總結起來就是:
ggplot(data, aes(x, y)) +
geom_type()
最常見的圖有散點圖、折線圖、曲線圖、條形圖、直方圖,分別對應geom_point(), geom_line(), geom_smooth(), geom_bar(), geom_histogram()。相應的aes中的變數不一定是x和y,對於條形圖和直方圖就只有一個變數x。
由於接下來的例子也主要來自mpg數據集,放個截圖介紹:
?mpg
1. manufacturer
2. model: model name
3. displ: engine displacement, in litres
4. year: year of manufacture
5. cyl: number of cylinders
6. trans: type of transmission
7. drv: f = front-wheel drive, r = rear wheel drive, 4 = 4wd
8. cty: city miles per gallon
9. hwy: highway miles per gallon
10. fl: fuel type
11. class: "type" of car
下面畫一個曲線圖:
ggplot(mpg, aes(cty, hwy)) +
geom_point() +
geom_smooth()
一張ggplot上可以疊加不同類型的圖,這裡直接在散點圖後面加上了曲線圖。
再來一個條形圖:
ggplot(mpg, aes(class)) +
geom_bar()
這裡畫的是每種車型對應的數量。
還可以擴展一下,讓不同的生產商對應不同顏色:
ggplot(mpg, aes(class, fill = manufacturer)) +
geom_bar()
在每一種車型下,不同的公司用不同顏色表示。是不是很棒?對,我也覺得~
過幾天來加升級ggplot2~
升級中---------------------
除了fill,還可以在aes裡面加color,size,shape:
color &<- ggplot(mpg, aes(cty, hwy, color = class)) + geom_point()
size &<- ggplot(mpg, aes(cty, hwy, size = class)) + geom_point()
shape &<- ggplot(mpg, aes(cty, hwy, shape = class)) + geom_point()
還有alpha,設置透明度,範圍在0到1之間。
加坐標軸名字和圖的標題:
ggplot(mpg, aes(cty, hwy)) +
geom_point() +
xlab("city miles per gallon") + #x軸名稱
ylab("highway miles per gallon") + #y軸名稱
ggtitle("city vs. highway miles per gallon") #圖標標題
到這裡基本上就可以滿足大多數的作圖要求了。不過以上的介紹遠遠沒有包括所有的圖型,介紹的幾種類型也沒有涵蓋所有的語法,如果想了解更多的話可以看最後的學習資料。
接下來說4. facet。facet可以把一張圖按變數分割成若干小圖。有facet_grid和facet_wrap兩種。下面的例子用facet_wrap按生產商分車型:
ggplot(mpg, aes(class)) +
geom_bar() +
facet_wrap(~manufacturer)
5. statistics 其實geom都包含了默認的stat,比如geom_bar默認的就是geom_bar(stat = "count")。所以下面例子里用stat_count( )的結果和geom_bar( )一樣。
ggplot(mpg, aes(class)) +
stat_count()
6. coordinate 常用的是coord_cartesian,用法是coord_cartesian(xlim = c(xmin, xmax), ylim = c(ymin, ymax))。coordinate系統主要控制坐標軸,告訴ggplot坐標軸上取值的範圍。還是以上圖為例,把y軸的範圍設置成0到80:
ggplot(mpg, aes(class)) +
geom_bar() +
coord_cartesian(ylim = c(0, 80))
7. theme 最後就是圖的個性化了。有些自帶的theme,比如theme_bw、theme_classic等等。下面用theme_classic舉例:
ggplot(mpg, aes(class)) +
geom_bar() +
theme_classic()
也可以自己設置,比如這樣:
ggplot(mpg, aes(class)) +
geom_bar() +
theme(panel.background = element_blank(),
legend.key = element_blank(),
legend.background = element_blank(),
strip.background = element_blank(),
plot.background = element_rect(fill = "#FEE0D2", color = "black", size = 3),
panel.grid = element_blank(),
axis.line = element_line(color = "black"),
axis.ticks = element_line(color = "black"),
strip.text = element_text(size = 16, color = "#99000D"),
axis.title.y = element_text(color = "#99000D", hjust = 0, face = "italic"),
axis.title.x = element_text(color = "#99000D", hjust = 0, face = "italic"),
axis.text = element_text(color = "black"),
legend.position = "none")
(喪心病狂啊)
看完以後可以用R package自帶的數據集練練手:
mtcars
diamond
iris
下面是一波自問自答-----------------
ggplot可以在同一張圖上表現兩個數據集的數據嗎?
可以。我很喜歡的一個例子來自Wickham,在同一張圖上畫了美國的歷史失業率和總統任期:
presidential &<- subset(presidential, start &> economics$date[1])
ggplot(economics) + #第一個數據集economics
geom_rect( #用第二個數據集presidential畫長方形(rectangle),用不同顏色表示不同黨派
aes(xmin = start, xmax = end, fill = party), ymin = -Inf, ymax = Inf, alpha = 0.2,
data = presidential #數據和第一層所用的數據不一樣,所以要明確data = ...
) +
geom_vline( #還是用presidential在每位總統上任時間畫豎線(vertical line)
aes(xintercept = as.numeric(start)),
data = presidential,
colour = "grey50", alpha = 0.5
) +
geom_text( #仍然是用presidential在每段任期內y軸2500的地方「畫」出總統的名字
aes(x = start, y = 2500, label = name),
data = presidential,
size = 3, vjust = 0, hjust = 0, nudge_x = 50
) +
geom_line(aes(date, unemploy)) + #以時間和失業人數作為x軸和y軸畫折線圖
scale_fill_manual(values = c("blue", "red")) #手動設置填充顏色
ggplot可以畫地圖嗎?
可以。下面的例子用ggplot2自帶map_data地圖數據包。R還有其他一些地圖包可以安裝。
world &<- map_data("world") #map_data內輸入world得到包括經緯度和國家的數據
head(world)
long lat group order region subregion
1 -69.89912 12.45200 1 1 Aruba &
2 -69.89571 12.42300 1 2 Aruba &
3 -69.94219 12.43853 1 3 Aruba &
4 -70.00415 12.50049 1 4 Aruba &
5 -70.06612 12.54697 1 5 Aruba &
6 -70.05088 12.59707 1 6 Aruba &
ggplot(world, aes(long, lat)) +
geom_polygon(aes(group = group)) + #本質是用經緯度畫多邊形
coord_quickmap() #地圖在上一步已經畫好了,這一步調整以適應地圖的比例
最後還是要再說一次,以上只是一個很簡要的介紹,更多內容參考下面的資料吧~
我的學習資源:
1. R for Data Science (Electronic Book) by Garrett Grolemund and Hadley Wickham (2016). Sebastopol, CA: O"Reilly Media, Inc. Retrieved from: http://r4ds.had.co.nz/
這個有電子版的!ggplot2在第三章Data Visualisation。
2. 有答案提到的ggplot2: Elegant Graphics for Data Analysis
Wickham, H., Sievert, C. (2016). ggplot2: elegant graphics for data analysis. Cham, Schweiz: Springer.
3. DataCamp的互動式網課ggplot par1和part2
Data Visualization with ggplot2
R ggplot2 Tutorial For Data Visualizations
4. 不算是學習資源的Data Visualization Cheat Sheet Cheatsheets
這個是R Studio出的總結表,對ggplot的歸納很全,適合對ggplot有一定了解以後作參考用。
天啊這種帖子都要扯那麼多
https://www.rstudio.com/wp-content/uploads/2015/03/ggplot2-cheatsheet.pdf
官方指南,兩頁紙就。 看完你就全會了。
我說兩本書吧
《ggplot2 數據分析與圖形藝術》
《R數據可視化手冊》
這兩本都有中文,都能下載到源代碼。
共勉。
ggplot2隻是grammar of graphics一個實現,能嘚瑟成這樣也是醉了
有個問題,現在在做生存分析的km折線圖,這個圖目前好像只能用plot去調用survfit函數的結果來產生一個有很多拐點的圖,如下圖,該圖數據量為21,看起來還比較清晰
但是如果數據量大的情況下,這個圖就會變得異常密集而且難看,急需做平滑處理。如下圖:
正巧今天搜到了您的ggplot教程,我回去試了幾下,也看了些幫助文檔,但是始終做不出survfit的生存圖。不知道ggplot能否做km生存曲線的圖。
Python科研統計作圖Plotnine+Seaborn+matplotlib替代R ggplot2系列!(一)
放著manual你不看 在這裡問個啥。。。
問下怎麼繪製下面的annotate,legend和annotate的顏色要對應
推薦閱讀:
※輔修計算機的學生該怎麼找計算機相關的工作?
※如何用R語言畫廣東省地圖(劃分出21個地級市的邊界)?
※好看的數據可視化的圖片是怎麼樣做的?
※R語言中,RCurl優勢在哪兒,做爬蟲的話用Python還是RCurl效率高?
※如何爬取網頁表格數據?