ggplot繪圖之基本語法
1.ggplot2圖形之基本語法:
ggplot2的核心理念是將繪圖與數據分離,數據相關的繪圖與數據無關的繪圖分離。按圖層作圖,保有命令式作圖的調整函數,使其更具靈活性,並將常見的統計變換融入到了繪圖中。
ggplot的繪圖有以下幾個特點:第一,有明確的起始(以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)。
ggplot2里的所有函數可以分為以下幾類:
用於運算(我們在此不講,如fortify_,mean_等)
初始化、展示繪圖等命令(ggplot,plot,print等)
按變量組圖(facet_等)
真正的繪圖命令(stat_,geom_,annotate),這三類就是實現一個函數一個圖層的核心函數。
微調圖型:嚴格意義上說,這一類函數不是再實現圖層,而是在做局部調整。
aes : 同樣適用於修改geom_XXX() aes參數控制了對哪些變量進行圖形映射,以及映射方式
圖形屬性(aes) 橫縱坐標、點的大小、顏色,填充色等
完整公式總結:
ggplot(data = , aes(x = , y = )) +
geom_XXX(...) + ... + stat_XXX(...) + ... +
annotate(...) + ... + labs(...) +
scale_XXX(...) + coord_XXX(...) + guides(...) + theme(...) +
facet_XXX(...)
#完整ggplot2繪圖示意:
library(ggplot2)
attach(iris)
p <- ggplot(data=iris,aes(x = Sepal.Length,y = Sepal.Width))
p + geom_point(aes(colour = Species)) + stat_smooth() +
labs(title = "Iris of Sepal.length \n According to the Sepal.Width") +
theme_classic() + theme_bw() +annotate("text",x=7,y=4,parse = T,label = "x[1]==x[2]",size=6, family="serif",fontface="italic", colour="darkred")
geom :表示幾何對象,它是ggplot中重要的圖層控制對象,因為它負責圖形渲染的類型。
幾何對象(geom_) 上面指定的圖形屬性需要呈現在一定的幾何對象上才能被我們看到,這些承載圖形屬性的對象可能是點,可能是線,可能是bar
stat :統計變換 比如求均值,求方差等,當我們需要展示出某個變量的某種統計特征的時候,需要用到統計變換
annotate:添加注釋 #由於設置的文本會覆蓋原來的圖中對應的位置,可以改變文本的透明度或者顏色 例: annotate(geom='text')會向圖形添加一個單獨的文本對象 annotate("text",x=23,y=200,parse=T,label = "x[1]==x[2]")
labs : labs(x = "這是 X 軸", y = "這是 Y 軸", title = "這是標題") ## 修改文字
scale_: 標度是一種函數,它控制了數學空間到圖形元素空間的映射。一組連續數據可以映射到X軸坐標,也可以映射到一組連續的漸變色彩。一組分類數據可以映射成為不同的形狀,也可以映射成為不同的大小,這就是與aes內的各種美學(shape、color、fill、alpha)調整有關的函數。
coord_:調整坐標,控制了圖形的坐標軸並影響所有圖形元素. 調整坐標 coord_flip()來翻轉坐標軸。使用xlim()和ylim()來設置連續型坐標軸的最小值和最大值 coord_cartesian(xlim=c(0,100),ylim=c(0,100))
guides:調整所有的text。
theme:調整不與數據有關的圖的元素的函數。theme函數采用了四個簡單地函數來調整所有的主題特征:element_text調整字體,element_line調整主題內的所有線,element_rect調整所有的塊,element_blank清空。theme(panel.grid =element_blank()) ## 刪去網格線
facet :控制分組繪圖的方法和排列形式
# 不指定數據集時,data = NULL
一個圖形對象就是一個包含數據,映射,圖層,標度,坐標和分面的列表,外加組件options
ggplot(數據, 映射) geom_xxx(映射, 數據) stat_xxx(映射, 數據)
# 通過“+”實現不同圖層的相應累加,且越往后的圖層表現在上方
點(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)
然后,就是按照你的需要一步步加圖層了(使用“+”)。
*********************
基本語法:
數據(data):將要展示的數據;
映射(mapping):數據中的變量到圖形成分的映射;
幾何對象(geom):用來展示數據的幾何對象,如geom_point,geom_bar,geom_abline;
圖形屬性(aes):圖形屬性決定了圖形的外觀,如字體大小、標簽位置及刻度線;
標度(scale):決定了變量如何被映射到圖形屬性上;
坐標(coordinate):數據如何被映射到圖中。如coord_cartesian:笛卡爾坐標、coord_polar:極坐標、coord_map:地理投影;
統計變換(stat):對數據進行匯總,如箱線圖:stat_boxplot、線圖:stat_abline、直方圖:stat_bin
分面(facet):用來描述數據如何被拆分為子集,以及對不同子集是如何繪制的。
位置調整(position):對圖形位置做精細控制。
創建ggplot對象:使用ggplot函數:
ggplot(data,mapping=aes(),...,environment=globalenv())
參數 | 描述 | 默認值 |
data | 要繪圖的數據框 | |
mapping | 一系列圖形屬性的映射 | aes() |
environment | 圖形屬性參數所在的環境 | globalenv() |
... |
幾何對象:
為了指定圖形類型,必須加入圖層,可采用layer()函數。可以使用“point”等短名稱來指定幾何對象。layer函數允許將幾何對象作為名稱和值的配對,這樣就不需要指出函數全名,而只需要geom_后面的部分。幾何對象如下:
幾何對象函數 | 描述 |
geom_abline | 線圖,由斜率和截距指定 |
geom_area | 面積圖(即連續的條形圖) |
geom_bar | 條形圖 |
geom_bin2d | 二維封箱的熱圖 |
geom_blank | 空的幾何對象,什么也不畫 |
geom_boxplot | 箱線圖 |
geom_contour | 等高線圖 |
geom_crossbar | crossbar圖(類似於箱線圖,但沒有觸須和極值點) |
geom_density | 密度圖 |
geom_density2d | 二維密度圖 |
geom_errorbar | 誤差線(通常添加到其他圖形上,比如柱狀圖、點圖、線圖等) |
geom_errorbarh | 水平誤差線 |
geom_freqpoly | 頻率多邊形(類似於直方圖) |
geom_hex | 六邊形圖(通常用於六邊形封箱) |
geom_histogram | 直方圖 |
geom_hline | 水平線 |
geom_jitter | 點、自動添加了擾動 |
geom_line | 線 |
geom_linerange | 區間,用豎直線來表示 |
geom_path | 幾何路徑,由一組點按順序連接 |
geom_point | 點 |
geom_pointrange | 一條垂直線,線的中間有一個點(與Crossbar圖和箱線圖相關,可以用來表示線的范圍) |
geom_polygon | 多邊形 |
geom_quantile | 一組分位數線(來自分位數回歸) |
geom_rect | 二維的長方形 |
geom_ribbon | 彩虹圖(在連續的x值上表示y的范圍,例如Tufte著名的拿破侖遠征圖) |
geom_rug | 觸須 |
geom_segment | 線段 |
geom_smooth | 平滑的條件均值 |
geom_step | 階梯圖 |
geom_text | 文本 |
geom_tile | 瓦片(即一個個的小長方形或多邊形) |
geom_vline | 豎直線 |
統計變換
統計變換函數 | 描述 |
stat_abline | 添加線條,用斜率和截距表示 |
stat_bin | 分割數據,然后繪制直方圖 |
stat_bin2d | 二維密度圖,用矩陣表示 |
stat_binhex | 二維密度圖,用六邊形表示 |
stat_boxplot | 繪制帶觸須的箱線圖 |
stat_contour | 繪制三維數據的等高線圖 |
stat_density | 繪制密度圖 |
stat_density2d | 繪制二維密度圖 |
stat_function | 添加函數曲線 |
stat_hline | 添加水平線 |
stat_identity | 繪制原始數據,不進行統計變換 |
stat_qq | 繪制Q-Q圖 |
stat_quantile | 連續的分位線 |
stat_smooth | 添加平滑曲線 |
stat_spoke | 繪制有方向的數據點(由x和y指定位置,angle指定角度) |
stat_sum | 繪制不重復的取值之和(通常用在三點圖上) |
stat_summary | 繪制匯總數據 |
stat_unique | 繪制不同的數值,去掉重復的數值 |
stat_vline | 繪制豎直線 |
標度函數
標度函數 | 描述 |
scale_alpha | alpha通道值(灰度) |
scale_brewer | 調色板,來自colorbrewer.org網站展示的顏色標度 |
scale_continuous | 連續標度 |
scale_data | 日期 |
scale_datetime | 日期和時間 |
scale_discrete | 離散值 |
scale_gradient | 兩種顏色構建的漸變色 |
scale_gradient2 | 3中顏色構建的漸變色 |
scale_gradientn | n種顏色構建的漸變色 |
scale_grey | 灰度顏色 |
scale_hue | 均勻色調 |
scale_identity | 直接使用指定的取值,不進行標度轉換 |
scale_linetype | 用線條模式來展示不同 |
scale_manual | 手動指定離散標度 |
scale_shape | 用不同的形狀來展示不同的數值 |
scale_size | 用不同大小的對象來展示不同的數值 |
坐標系
坐標函數 | 描述 |
coord_cartesian | 笛卡兒坐標 |
coord_equal | 等尺度坐標(斜率為1) |
coord_flip | 翻轉笛卡兒坐標 |
coord_map | 地圖投影 |
coord_polar | 極坐標投影 |
coord_trans | 變換笛卡兒坐標 |
分面
分面函數 | 描述 |
facet_grid | 將分面放置在二維網格中 |
facet_wrap | 將一維的分面按二維排列 |
位置
定位函數 | 描述 |
position_dodge | 並列 |
position_fill | 填充 |
position_identity | 不對位置進行處理 |
position_jitter | 擾動處理 |
position_stack | 堆疊處理 |
Chap1. R 基礎
## 加載文件
- 默認情況下,數據集中的字符串(String)會被視為因子(Factor)處理,此時可以設置
stringAsFactors = FALSE
,將文本變量視為字符串表示。 - 讀取xlsx和xls文件:package
xlsx
(Java)和gdata
(Perl) foreign
:read.spss;read.octave;read.systat;read.xport;read.dta
Chap2. 快速探索數據(略)
## 概述 qplot()
函數的語法與基礎繪圖系統類似,簡短易輸入,通常用於探索性數據分析。qplot(x,y,data,geom=c(xx,xx))
條形圖
barplot()
第一個向量用來設定條形的高度,第二個向量用來設定每個條形對應的標簽(可選)。變量值條形圖
: 兩個輸入變量,x為分類變量,y表示變量值頻數條形圖
:一個輸入變量,需要注意連續x軸和離散x軸的差異。
直方圖
與條形圖不同的地方在於,x為連續型變量
箱線圖
- 需要傳遞兩個向量:x和y
- 在x軸上引入兩變量的交互:
interaction()
- Question:基礎繪圖系統和ggplot2的箱線圖略有不同。
繪制函數圖像
ggplot(data.frame(x=c(0,20)), aes(x=x)) + stat_function(fun=myfun, geom = "line")
Chap3. 條形圖
重要細節:條形圖的高度表示的是數據集中變量的頻數,還是表示變量取值本身
## 概述 條形圖通常用來展示不同的分類下(x軸)某個數值型變量的取值(y軸),其條形高度既可以表示數據集中變量的頻數,也可以表示變量取值本身。
參數
fill
:改變條形圖的填充色;colour
:添加邊框線;position
:改變條形圖的類型;linetype
:線型scale_fill_brewer()
和scale_fill_manual()
設置顏色scale_fill_brewer(palette="Pastell")
條形圖
- 頻數條形圖:只需要一個輸入變量,當變量為連續型變量時,等價於直方圖。
- 顏色映射在
aes()
內部完成,而顏色的重新設定在aes()
外部完成。 - 排序:
ggplot(upc, aes=(x=reorder(Abb, Change)), y =Change, fill = Region)
- 正負條形圖着色:首先,創建一個對取值正負情況進行標示的變量,然后參數設定為
position='identity'
,這可以避免系統因對負值繪制堆積條形而發出的警告信息。 guide=FALSE
刪除圖例width
調整條形圖的條形寬度;position_dodge(0.7)
調整條形間距(中心距離)- 堆積條形圖:
geom_bar(stat='identity')
默認情況 - 更改圖例顏色順序:
guides(fill = guide_legend(reverse=TRUE))
- 調用調色板
scale_fill_brewer(palette='Pastell')
和手動:scale_fill_manual()
- 百分比堆積圖:首先利用plyr包種的ddply()轉化數據,然后再繪圖.
- 添加 數據標簽:
geom_text(aes(y = label_y, label=Weight),vjust=xxx)
其中y用來控制標簽的位置 - 繪制Cleveland點圖:通常都會設置成根據x軸對應的連續變量的大小取值對數據進行排序。
reorder(x,y)
:先將x轉化為因子,然后根據y對其進行排序。- 主題系統(Theming System):
theme(panel.grid.major.x = element_blank(),panel.grid.minor.x = element_blank())
匯總好的數據集繪制條形圖:
x <- c('A','B','C','D','E')
y <- c(13,22,16,31,8)
df <- data.frame(x= x, y = y)
ggplot(data = df, mapping = aes(x = x, y = y)) + geom_bar(stat= 'identity')
對於條形圖的y軸就是數據框中原本的數值時,必須將geom_bar()函數中stat(統計轉換)參數設置為’identity’,即對原始數據集不作任何統計變換,而該參數的默認值為’count’,即觀測數量。
使用明細數據集繪制條形圖:
-
set.seed(1234)
x <- sample(c('A','B','C','D'), size = 1000, replace= TRUE, prob = c(0.2,0.3,0.3,0.2))
y <- rnorm(1000) * 1000
df = data.frame(x= x, y = y)
ggplot(data = x = x, mapping = aes(x = factor(x), y = ..count..))+ geom_bar(stat = 'count')
數據集本身是明細數據,而對於統計某個離散變量出現的頻次時,geom_bar()函數中stat(統計轉換)參數只能設置為默認,即’count’。
當然,如果需要對明細數據中的某個離散變量進行聚合(均值、求和、最大、最小、方差等)后再繪制條形圖的話,建議先使用dplyr包中的group_by()函數和summarize()函數實現數據匯總,具體可參見:
從x軸的數據類型來看:有字符型的x值也有數值型的x值
上面的兩幅圖對應的x軸均為離散的字符型值,如果x值是數值型時,該如何正確繪制條形圖?
set.seed(1234)
x <- sample(c(1,2,4,6,7), size = 1000, replace = TRUE,prob = c(0.1,0.2,0.2,0.3,0.2))
ggplot(data = data.frame(x = x), mapping= aes(x = x, y = ..count..)) + geom_bar(stat = 'count')
如果直接使用數值型變量作為條形圖的x軸,我們會發現條形圖之間產生空缺,這個空缺其實對應的是3和5兩個值,這樣的圖形並不美觀。為了能夠使條形圖之間不存在類似的空缺,需要將數值型的x轉換為因子,即factor(x),如下圖所示:
ggplot(data = data.frame(x = x), mapping = aes(x = factor(x), y = ..count..))+ geom_bar(stat = 'count')
上面幾幅圖的顏色均為灰色的,顯得並不是那么亮眼,為了使顏色更加豐富多彩,可以在geom_bar()函數內通過fill參數可colour參數設置條形圖的填充色和邊框色,例如:
ggplot(data = data.frame(x = x), mapping = aes(x = factor(x), y = ..count..))+ geom_bar(stat = 'count', fill = 'steelblue', colour = 'darkred')
關於顏色的選擇可以在R控制台中輸入colours(),將返回657種顏色的字符。如果想查看所有含紅色的顏色值,可以輸入colours()[grep(‘red’,
colours())]返回27種紅色。
繪制簇條形圖
以上繪制的條形圖均是基於一個離散變量作為x軸,如果想繪制兩個離散變量的條形圖即簇條形圖該如何處理呢?具體見下方例子:
x <- rep(1:5, each = 3)
y <- rep(c('A','B','C'),times = 5)
set.seed(1234)
z <- round(runif(min = 10, max = 20, n = 15)) df <- data.frame(x= x, y = y, z = z)
ggplot(data = df, mapping = aes(x = factor(x), y = z,fill = y)) + geom_bar(stat = 'identity', position = 'dodge')
對於簇條形圖只需在ggplot()函數的aes()參數中將其他離散變量賦給fill參數即可。這里的position參數表示條形圖的擺放形式,默認為堆疊式(stack),還可以是百分比的堆疊式。下面分別設置這兩種參數,查看一下條形圖的擺放形式。
堆疊式:
ggplot(data = df, mapping = aes(x = factor(x), y = z, fill = y)) + geom_bar(stat= 'identity', position = 'stack')
發現一個問題,條形圖的堆疊順序(A,B,C)與圖例順序(C,B,A)恰好相反,這個問題該如何處理呢?很簡單,只需再添加guides()函數進行設置即可,如下所示:
ggplot(data = df, mapping = aes(x = factor(x), y = z, fill = y)) + geom_bar(stat= 'identity', position = 'stack') + guides(fill = guide_legend(reverse= TRUE))
guides()函數將圖例引到fill屬性中,再使圖例反轉即可。
百分比堆疊式:
ggplot(data = df, mapping = aes(x = factor(x), y = z, fill = y)) + geom_bar(stat= 'identity', position = 'fill')
顏色配置:
同樣,如果覺得R自動配置的填充色不好看,還可以根據自定義的形式更改條形圖的填充色,具體使用scale_fill_brewer()和scale_fill_manual()函數進行顏色設置。
scale_fill_brewer()函數使用R自帶的ColorBrewer畫板
ggplot(data = df, mapping = aes(x = factor(x), y = z, fill = y)) + geom_bar(stat= 'identity', position = 'dodge') + scale_fill_brewer(palette = 'Accent')
具體的調色板顏色可以查看scale_fill_brewer()函數的幫助。
scale_fill_manual()函數允許用戶給指定的分類水平設置響應的色彩,個人覺得這個比較方便
col <- c('darkred','skyblue','purple')
ggplot(data = df, mapping =aes(x = factor(x), y = z, fill = y)) + geom_bar(stat = 'identity', colour= 'black', position = 'dodge') + scale_fill_manual(values = col, limits= c('B','C','A')) + xlab('x')
-
a <- ggplot(mpg, aes(x=hwy))
-
a + stat_bin(aes(fill=..count.., color=-1*..ndensity..), binwidth = 1)
統計方法有輸入,有輸出。通常輸入為x和y。輸出值會以例的形式追加到當前操作的數據拷貝中。比如上例中的stat_bin函數,就會生成四列新數據,分別為count, density, ncount以及ndensity。在訪問這些新列的時候,使用..name..的方式。
該如何繪制有序的條形圖?
#不經排序的條形圖,默認按x值的順序產生條形圖
x <- c('A','B','C','D','E','F','G')
y <-c('xx','yy','yy','xx','xx','xx','yy')
z <- c(10,33,12,9,16,23,11)
df<- data.frame(x = x, y = y, z = z)
ggplot(data = df, mapping = aes(x= x, y = z, fill = y)) + geom_bar(stat = 'identity')
按z值的大小,重新排列條形圖的順序,只需將aes()中x的屬性用reorder()函數更改即可。
ggplot(data = df, mapping = aes(x = reorder(x, z), y = z, fill = y)) +geom_bar(stat = 'identity') + xlab('x')
關於條形圖的微調
如何y軸的正負值區分開來,並去除圖例
-
set.seed(12)
x <- 1980 + 1:35
y <- round(100*rnorm(35))
df <- data.frame(x = x,y = y)
# 判斷y是否為正值
df <- transform(df,judge = ifelse(y>0,"YES","NO"))
# 去除圖例用theme()主題函數
ggplot(df,aes(x = x,y = y,fill = judge))+
geom_bar(stat = "identity")+
theme(legend.position= "")+
xlab("Year")+
scale_fill_manual(values = c("darkred","blue"))
stat參數和position參數均設置為identity,目的是圖形繪制不要求對原始數據做任何的變換,包括統計變換和圖形變換,排除圖例可以通過scale_fill_manual()函數將參數guide設置為FALSE,同時該函數還可以自定義填充色,一舉兩得。
ggplot(data = df, mapping = aes(x = x, y = y, fill = judge))+
geom_bar(stat = 'identity', position = 'identity')+
scale_fill_manual(values = c('blue','red'), guide = FALSE)+
xlab('Year')
調整條形圖的條形寬度和條形間距
geom_bar()函數可以非常靈活的將條形圖的條形寬度進行變寬或變窄設置,具體通過函數的width參數實現,width的最大值為1,默認為0.9。
x <- c("A","B","C","D","E")
y <- c(10,20,15,22,18)
df <- data.frame(x = x,y = y)
# 不作任何條形寬度的調整
ggplot(df,aes(x = x,y = y))+
geom_bar(stat = "identity",fill = "steelblue",colour = "black")
# 使條形寬度變寬
ggplot(df,aes(x = x,y = y))+geom_bar(stat = "identity",fill = "steelblue",colour = "black",width = 1)
對於簇條形圖來說,還可以調整條形之間的距離,默認情況下,條形圖的組內條形間隔為0,具體可通過函數的position_dodge參數實現條形距離的調整,為了美觀,一般將條形距離設置的比條形寬度大一點。
-
x <- rep(1:5,each = 3)
y <- rep(c("A","B","C"),times = 5)
set.seed(12)
z <- round(runif(min = 10,max = 20,n = 15))
df <- data.frame(x = x,y = y,z = z)
# 不做任何條形寬度和條形距離的調整
ggplot(df,aes(x = factor(x),y = z,fill = y))+
geom_bar(stat = "identity",position = "dodge")
調整條形寬度和條形距離
ggplot(data = df, mapping = aes(x = factor(x), y = z, fill = y)) + geom_bar(stat= 'identity', width = 0.5, position = position_dodge(0.7))
添加數據標簽
geom_text()函數可以方便的在圖形中添加數值標簽,具體微調從幾個案例開始:
-
# 添加標簽
ggplot(df,aes(x = interaction(x,y),y = z,fill = y))+
geom_bar(stat = "identity")+
geom_text(aes(label = z))
除此之外,還可以調整標簽的大小、顏色、位置等。
ggplot(data = df, mapping = aes(x = interaction(x,y), y = z, fill = y))+ geom_bar(stat = 'identity') + ylim(0,max(z)+1) + geom_text(mapping =aes(label = z), size = 8, colour = 'orange', vjust = 1)
ylim設置條形圖中y軸的范圍;size調整標簽字體大小,默認值為5號;colour更換標簽顏色;vjust調整標簽位置,1為分界線,越大於1,標簽越在條形圖上界下方,反之則越在條形圖上上界上方。
# vjust 調整標簽豎直位置,越大,標簽越在條形圖的上界下方;0.5時,則在中間。
# hjust 調整標簽水平位置,越大,標簽越在條形圖的上界左邊;0.5時,則在中間。
對於水平交錯的簇條形圖,必須通過geom_text()函數中的position_dodge()參數來調整標簽位置,hjust=0.5將標簽水平居中放置。
ggplot(data = df, mapping = aes(x = x, y = z, fill = y)) + geom_bar(stat
= 'identity', position = 'dodge') + geom_text(mapping = aes(label = z),
size = 5, colour = 'black', vjust = 1, hjust = .5, position = position_dodge(0.9))
這里的圖形位置與標簽位置擺放必須一致,即圖形位置geom_bar()函數中的position = 'dodge'參數,標簽位置geom_text()函數中的position
= position_dodge(0.9)參數。
對於堆疊的簇條形圖,必須通過geom_text()函數中的position_stack()參數來調整標簽位置,hjust將標簽水平居中放置。
ggplot(data = df, mapping = aes(x = x, y = z, fill = y)) + geom_bar(stat
= 'identity', position = 'stack') + geom_text(mapping = aes(label = z),
size = 5, colour = 'black', vjust = 3.5, hjust = .5, position = position_stack())
這里的圖形位置與標簽位置擺放必須一致,即圖形位置geom_bar()函數中的position = 'stack'參數,標簽位置geom_text()函數中的position
= position_stack()參數。
補充:統計變換
若x軸變量為連續的,則用sta = bin;
若離散型的,可用stat = “count”或stat = “identity”
參考資料
R數據可視化手冊
R語言_ggplot2:數據分析與圖形藝術
Chap4. 折線圖
概述
折線圖可以反映某種現象的趨勢。通常折線圖的橫坐標是時間變量,縱坐標則是一般的數值型變量。當然,折線圖也允許橫縱坐標為離散型和數值型。
折線圖通常用來對兩個連續變量之間的相互依存關系進行可視化。其中x也可以是因子型變量。
簡單折線圖
geom_line()
- 對於因子型變量,必須使用
aes(group=1)
以確保ggplot()
知道這些數據點屬於同一個分組,從而應該用一條折線連在一起。 - 數據標記相互重疊:需要相應地左移或者右移連接線以避免點線偏離。
geom_line(position=position_dodge(0.2))
- 參數:線型(linetype),線寬(size),顏色(colour):邊框線
- 在
aes()
函數外部設定顏色、線寬、線型和點型等參數會將所有目標對象設定為同樣的參數值。 - 面積圖:
geom_area()
,alpha調節透明度 - 堆積面積圖:
geom_area()
基礎上,映射一個因子型比那里給填充色(fill)即可 - 添加置信域:
geom_ribbon()
,然后分貝映射一個變量給ymin和ymax。geom_ribbon(aes(ymin=xx,ymax=xx), alpha = 0.2)
一、繪制單條折線圖
library(ggplot2)
library(lubridate) #處理日期時間相關的R包,非常有用,強烈推薦
Year <- year(seq(from = as.Date('2006-01-01'), to = as.Date('2015-01-01'), by = 'year'))
Weight <- c(23,35,43,57,60,62,63,66,61,62)
df <- data.frame(Year = Year, Weight = Weight)
ggplot(data = df, mapping = aes(x = factor(Year), y = Weight, group = 1)) + geom_line() + xlab('Year')
有關離散變量的折線圖
type <- c('A','B','C','D','E')
quanlity <- c(1,1.1,2.1,1.5,1.7)
df <- data.frame(type = type, quanlity = quanlity)
ggplot(data = df, mapping = aes(x = type, y = quanlity, group = 1)) + geom_line()
有關連續變量的折線圖
set.seed(1234)
times <- 1:15
value <- runif(15,min = 5,max = 15)
df <- data.frame(times = times, value = value)
ggplot(data = df, mapping = aes(x = times, y = value)) + geom_line()
善於發現的你,可能會注意到上面三段代碼有一個重要的不同之處,那就是第一段和第二段代碼中含有‘group = 1’的設置。這樣做是因為橫坐標的屬性設置為了因子,即將連續型的年份和離散型的字符轉換為因子,如果不添加‘group = 1’這樣的條件,繪圖將會報錯。故務必需要記住這里的易犯錯誤的點!
往折線圖中添加標記(點) 當數據點密度比較小或采集分布(間隔)不均勻時,為折線圖做上標記將會產生非常好的效果。處理的方法非常簡單,只需在折線圖的基礎上再加上geom_point()函數即可。
set.seed(1234)
year <- c(1990,1995,2000,2003,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015)
value <- runif(15, min = 10, max = 50)
df <- data.frame(year = year, value = vlaue)
ggplot(data = df, mapping = aes(x = year, y = value)) + geom_line() + geom_point()
從圖中就可以非常明顯的看出,剛開始采集的點分布非常散,而后面采集的點就比較密集,這也有助於對圖的理解和應用。
二、繪制多條折線圖 上面繪制的都是單條這折線圖,對於兩個或兩個以上的折線圖該如何繪制呢?也很簡單,只需將其他離散變量賦給諸如colour(線條顏色)和linetype(線條形狀)的屬性即可,具體參見下文例子。
基於顏色的多條折線圖
set.seed(1234)
year <- rep(1990:2015, times = 2)
type <- rep(c('A','B'),each = 26)
value <- c(runif(26),runif(26, min = 1,max = 1.5))
df <- data.frame(year = year, type = type, value = value)
ggplot(data = df, mapping = aes(x = year, y = value, colour = type)) + geom_line()
基於形狀的多條折線圖
ggplot(data = df, mapping = aes(x = year, y = value, linetype= type)) + geom_line()
同樣需要注意的是,在繪制多條折線圖時,如果橫坐標為因子,必須還得加上‘group=分組變量’的參數,否則報錯或繪制出錯誤的圖形。
以上繪制的折線圖,均采用默認格式,不論是顏色、形狀、大小還是透明度,均沒有給出自定義的格式。其實ggplot2包也是允許用戶根據自己的想法設置這些屬性的。
自定義線條或點的顏色—scale_color_manual()
自定義線條類型—scale_linetype_manual()
自定義點的形狀—scale_shape__manual()
自定義點的大小或線條的寬度—scale_size__manual()
自定義透明度—scale_alpha__manual()
綜合的例子:
ggplot(data = df, mapping = aes(x = year, y = value, linetype = type, colour = type, shape = type, fill = type))+ geom_line() + geom_point() #繪制線圖和點圖
+ scale_linetype_manual(values = c(1,2)) #自定義線條類型
+ scale_color_manual(values = c('steelblue','darkred')) #自定義顏色
+ scale_shape_manual(values = c(21,23)) #自定義點形狀
+ scale_fill_manual(values = c('red','black')) #自定義點的填充色
雖然這幅圖畫的優點誇張,目的是想說明可以通過自定義的方式,想怎么改就可以怎么改。前提是aes()屬性的內容與自定義的內容對應上。
三、繪制堆積面積圖
繪制堆疊的面積圖只需要geom_area()函數再加上一個離散變量映射到fill就可以輕松實現,先忙咱小試牛刀一下。
set.seed(1234)
year <- rep(1990:2015, times = 2)
type <- rep(c('A','B'),each = 26)
value <- c(runif(26),runif(26, min = 1,max = 1.5))
df <- data.frame(year = year, type = type, value = value)
ggplot(data = df, mapping = aes(x = year, y = value, fill = type)) + geom_area()
一幅堆疊的面積圖就輕松繪制成功,但我們發現,堆疊的順序與圖例的順序恰好相反,不用急,只需要加一句命令即可:
ggplot(data = df, mapping = aes(x = year, y = value, fill = type)) + geom_area() + guides(fill = guide_legend(reverse = TRUE))
如果需要為每一塊面積圖的頂部加上一條直線,可以通過如下兩種方式:
ggplot(data = df, mapping = aes(x = year, y = value, fill = type)) + geom_area(colour = 'black', size =1, alpha = .7) + guides(fill = guide_legend(reverse = TRUE))
其中,colour設置面積圖邊框的顏色;size設置邊框線的粗細;alpha設置面積圖和邊框線的透明度。
ggplot(data = df, mapping = aes(x = year, y = value, fill = type)) + geom_area(alpha = 0.6) + geom_line(colour = 'black', size = 1, position = 'stack', alpha = 0.6) + guides(fill = guide_legend(reverse = TRUE))
該方法是通過添加堆疊線條(必須設置geom_line()中position參數為‘stack’,否則只是添加了兩條線,無法與面積圖的頂部重合)。這兩幅圖的區別在於第二種方式沒有繪制面積圖左右邊框和底邊框。在實際應用中,建議不要在面積圖中繪制邊框線,因為邊框的存在可能產生誤導。
四、繪制百分比堆積面積圖
在面積圖中,也可以方便快捷的繪制出百分比堆積面積圖,具體操作如下:
set.seed(1234)
year <- rep(1990:2015, times = 4)
type <- rep(c('A','B','C','D'),each = 26)
value <- c(runif(26),runif(26, min = 1,max = 1.5), runif(26, min = 1.5,max = 2), runif(26, min = 2,max = 2.5))
df <- data.frame(year = year, type = type, value = value)
ggplot(data = df, mapping = aes(x = year, y = value, fill = type)) + geom_area(position = 'fill', alpha = 0.6) + guides(fill = guide_legend(reverse = TRUE))
但通過這種方式(設置面積圖的positon='fill')存在一點點小缺陷,即無法繪制出百分比堆積面積圖頂部的線條,該如何實現呢?這里只需要對原始數據集做一步匯總工作,讓后按部就班的繪制面積圖即可。
library(dplyr)
df_by_type <- group_by(.data = df, year)
df_summarize <- mutate(.data = df_by_type, value2 = value/sum(value))
有關dplyr包的用法可參考:
強大的dplyr包實現數據預處理
ggplot(data = df_summarize, mapping = aes(x = year, y = value2, fill = type)) + geom_area(alpha = 0.6) + geom_line(colour = 'black', size = 1, position = 'stack', alpha = 0.6) + guides(fill = guide_legend(reverse = TRUE))
哈哈,大功告成,就這么簡單。
Chap5. 散點圖
概述
散點圖通常用來刻畫兩個連續型變量之間的關系。
散點圖
geom_point()
- 參數值:
shape()
,size=2
,colour()
- 更改配色與點形:
scale_colour/shape_brewer/manual()
- 盡量將不需要高精度的變量映射給圖形的大小和顏色屬性。
- 調用
scale_size_area()
函數使數據點的面積正比於變量值。 - 處理圖形重疊問題(overplotting):
- 使用半透明的點
- 將數據分箱(bin),並用矩形表示(適用於量化分析)
stat_bin2d()
- 將數據分箱(bin),並用六邊形表示
stat_binhex
(packages:”hexbin”) - 使用箱線圖
- 離散x:調用
geom_point(position_jitter())
函數給數據點增加隨機擾動。
- 添加回歸模型擬合線:
stat_smooth(method=lm,level=0.95)
- 添加自己構建的模型擬合線:
geom_line(data=predicted,size=1)
dlply()
和ldply()
函數:切分數據,對各個部分執行某一函數,並對執行結果進行重組。- 散點圖中添加模型系數:
+ annotate(parse = TRUE)
函數添加文本。利用expression()
檢驗輸出結果 - 添加邊際地毯(Marginal rugs):
geom_rug()
- 添加標簽:
geom_text(aes(label=xxx),size=xx,x=xx+0.1)
vjust=1
:標簽文本的頂部與數據點對齊vjust=0
:標簽文本的底部與數據點對齊hjust=1/0
:右對齊/左對齊- 通常先設定
hjust()
和vjust()
的值為0或1,然后再調整x或y的值來調整文本標簽的位置. - 對數坐標軸:需令x或者y乘以一個數值才可以。
- 去掉不需要的標簽:將不需要刻畫出來的標簽賦值為
NA
- 繪制氣泡圖:
geom_point()
和scale_size_area(max_size=15)
- 散點圖矩陣:base基礎繪圖系統,
pairs()
散點圖通常用來刻畫兩個連續型變量之間的關系,數據集中的每一條觀測都由散點圖中的一個點來表示。在散點圖中也可以加入一些直線或曲線,用來表示基於統計模型的擬合。當數據集記錄很多時,散點圖可能會彼此重疊,這種情況往往需要一些預處理操作。
1 基本散點圖
散點圖可以用來描述兩個連續變量之間的關系,一般在做數據探索分析時會使用到,通過散點圖發現變量之間的相關性強度、是否線性關系等。
使用geom_point()繪制散點圖,並分別映射一個變量到x和y。
1 2 |
library(gcookbook) ggplot(heightweight, aes(x=ageYear, y=heightIn)) + geom_point() |
可以使用shape和size分別指定點型和點的大小,如果點型包括填充和描邊的話,可用fill和color分別指定填充色和描邊色。
2 基於類別型變量分組
可將分組變量(因子或字符變量)賦值給顏色或形狀屬性,實現分組散點圖的繪制
可以將因子和字符串等類別型變量映射到散點的顏色或形狀。
1 2 |
library(gcookbook) ggplot(heightweight, aes(x=ageYear, y=heightIn, shape=sex, color=sex)) + geom_point() |
set.seed(112)
x <- rnorm(100,mean = 2,sd = 3)
y <- 1.5+2*x+rnorm(100)
z <- sample(c(0,1),size = 100,replace = TRUE)
df <- data.frame(x = x,y = y,z = z)
# 將數值型變量轉換為因子型變量
df$z <- factor(df$z)
#分組變量賦值給顏色屬性
ggplot(df,aes(x = x,y = y,colour = z))+
geom_point(size = 3)
#分組變量賦值給形狀屬性
ggplot(df,aes(x = x,y = y,shape = z))+
geom_point(size = 3)
# 分組變量同時賦給顏色屬性和形狀屬性
ggplot(df,aes(x = x,y = y,shape = z,colour = z))+
geom_point(size = 3)+
scale_color_brewer(palette = "Accent")+
scale_shape_manual(values = c(2,16))
注意點的形狀,21-25之間的點的形狀,既可以賦值邊框顏色,又可以賦值填充色。
將離散型變量或因子映射給顏色屬性或形狀屬性
-
x <- c(10,13,11,15,18,20,21,22,24,26)
-
y <- c(76,60,70,58,55,48,44,40,26,18)
-
z <- c(100,120,300,180,80,210,30,95,145,420)
-
df <- data.frame(x = x,y = y,z = z)
-
# 將連續型變量映射給顏色屬性
-
ggplot(df,aes(x = x,y = y,colour = z))+
-
geom_point(size = 3)
圖例上,顏色越深而對應的值越小,如何將值的大小與顏色的深淺保持一致?只需要人為的設置色階,從低到高設置不同的顏色即可
3 基於連續型變量映射
當然,還可以將連續型變量映射到散點的顏色或大小等存在漸變的屬性上,從而呈現三個連續型變量之間的關系。其中人眼對於x軸和y軸所對應變量的變化更為敏感,而對顏色和大小的變化則不那么敏感。
1 2 |
library(gcookbook) ggplot(heightweight, aes(x=ageYear, y=heightIn, size=weightLb, color=weightLb)) + geom_point() |
同時映射類別型變量和連續型變量,並設置散點的面積正比於連續型變量的大小,默認為非線性映射。
1 2 |
library(gcookbook) ggplot(heightweight, aes(x=ageYear, y=heightIn, size=weightLb, color=sex)) + geom_point(alpha=.5) + scale_size_area() |
# 將連續型變量映射給顏色屬性,同時設置雙色梯度
ggplot(df,aes(x = x,y = y,colour = z))+geom_point(size = 3)+scale_colour_gradient(low = "lightblue",high = "darkblue")
# 將連續變量映射給大小屬性
ggplot(df,aes(x = x,y = y,size = z))+ geom_point()
# 將連續型變量賦給顏色屬性或大小屬性,自定義雙色梯度,色階間隔順序由低到高
ggplot(df,aes(x = x,y = y,fill = z))+ geom_point(shape = 21,size = 3)+
scale_fill_gradient(low = "lightblue",high = "darkblue",breaks = c(100,150,200,300,350,400))
# 自定義球大小的間隔
ggplot(df,aes(x = x,y = y,size = z))+geom_point()+
scale_size_continuous(breaks = c(100,150,200,250,300,350,400),guide = guide_legend())
# scale_size(breaks = c(100,150,200,250,300,350,400))結果一樣
# 將連續變量值的大小與球的大小成比例
ggplot(df,aes(x = x,y = y,size = z))+geom_point()+scale_size_area(max_size = 10)
# scale_size_area()可以確保數值0映射為0,max_size保證映射最大的點的大小
4 處理散點重合
處理散點重合的基本思路包括:
當數據點非常多時,可能會導致數據點重疊嚴重,處理方法如下:
1)使用半透明的點
2)數據分箱,並用矩形表示{stat_bin2d()}
3)數據分箱,並用六邊形表示{stat_binhex()}
4)使用二維密度估計,並將等高線添加到散點圖中{stat_density2d()}
5)向散點圖中添加邊際地毯
set.seed(112)
x <- rnorm(10000)
y <- rnorm(10000,0,2)
df <- data.frame(x = x,y = y)
# 不作任何處理
ggplot(df,aes(x = x,y = y))+
geom_point()
# 使用透明度處理點的重疊問題
ggplot(df,aes(x = x,y = y))+geom_point(alpha = 0.1)
# 分箱,並用矩陣表示
ggplot(df,aes(x = x,y = y))+stat_bin2d()
默認情況下,stat_bin2d()函數將x軸和y軸的數據點各分位30段,即參數900個箱子;用戶還可以自定義分段個數,以及箱子在垂直和水平方向上的寬度。
# 設置bins為50,
ggplot(df,aes(x = x,y = y))+stat_bin2d(bins = 50)+scale_fill_gradient(low = "steelblue",high = "darkred",limits = c(0,100),breaks = c(0,25,50,100))
分箱的具體做法是,將點分箱,並統計每個箱中點的個數,然后通過某種方法可視化這個數量。
# 分箱,用六邊形表示,箱子水平和豎直方向的寬度各為0.2,0.3;
# 圖例標度范圍0-100,顯示在圖例上的值(0,25,50,100)
ggplot(df,aes(x = x,y = y))+stat_bin_hex(binwidth = c(0.2,0.3))+
scale_fill_gradient(low = "lightgreen",high = "darkred",limits=c(0,100),breaks = c(0,25,50,100))
# 使用stat_density2d作二維密度估計,並將等高線添加到散點圖中
ggplot(df,aes(x = x,y = y))+geom_point()+stat_density2d()
#使用大小與分布密度成正比例的點,不添加等高線
ggplot(df,aes(x = x, y = y)) +stat_density2d(geom = 'point', aes(size = ..density..),contour = FALSE) + scale_size_area()
#使用瓦片圖展示數據分布密度情況
ggplot(df,aes(x = x, y = y)) + stat_density2d(geom = 'tile',aes(fill = ..density..),contour = FALSE)
#向散點圖中添加邊際地毯(軸須線)
ggplot(faithful,aes(x = eruptions, y = waiting)) + geom_point() + geom_rug()
#通過邊際地毯,可以快速查看每個坐標軸上數據的分布密疏情況。還可以通過向邊際地毯線的位置坐標添加擾動並設定size減少線寬,從而減輕邊際地毯線的重疊程度。
ggplot(faithful, aes(x = eruptions, y = waiting)) +geom_point() +geom_rug(position = 'jitter', size = 0.1)
- 設置透明度;
- 使用矩形和六邊形等分箱,並且用顏色表示密度。
1 2 3 4 5 6 7 8 9 10 11 |
sp <- ggplot(diamonds, aes(x=carat, y=price)) # 未處理 sp + geom_point() # 設置透明度 sp + geom_point(alpha=.1) sp + geom_point(alpha=.01) # 矩形分箱並設置漸變顏色 sp + stat_bin2d(bins=50) + scale_fill_gradient(low="lightblue", high="red") # 六邊形分箱並設置漸變顏色 install.packages("hexbin") sp + stat_binhex() + scale_fill_gradient(low="lightblue", high="red") |
以下為六邊形分箱的結果。
當x軸和y軸對應一個或兩個離散型變量時,例如雖然對應數值,但是數值僅取某些離散點,可以給散點圖添加擾動,使得散點分離開來。
1 2 3 4 5 6 7 |
sp <- ggplot(ChickWeight, aes(x=Time, y=weight)) # 未處理 sp + geom_point() # 添加擾動 sp + geom_point(position="jitter") # 僅添加水平方向上的擾動 sp + geom_point(position=position_jitter(width=.5, height=0)) |
5 添加擬合線
使用stat_smooth()或geom_smooth()添加擬合線和置信域。
1 2 3 4 5 6 7 8 9 10 11 12 |
library(gcookbook) sp <- ggplot(heightweight, aes(x=ageYear, y=heightIn)) # 默認,loess局部加權多項式擬合 sp + geom_point() + stat_smooth() # 線性擬合,95%置信域 sp + geom_point() + stat_smooth(method=lm) # 99%置信域 sp + geom_point() + stat_smooth(method=lm, level=0.99) # 不加置信域 sp + geom_point() + stat_smooth(method=lm, se=FALSE) # 修改配色 sp + geom_point(color="grey60") + stat_smooth(method=lm, se=FALSE, color="black") |
以下使用Logistic回歸擬合一個二分類的樣本,可以看出V1和classn具有二分類關系,Logistic回歸曲線也說明了這一點。
1 2 3 4 5 6 |
library(MASS) b <- biopsy b$classn[b$class=="benign"] <- 0 b$classn[b$class=="malignant"] <- 1 head(b) ggplot(b, aes(x=V1, y=classn)) + geom_point(position=position_jitter(width=.3, height=.06), alpha=.4, shape=21, size=1.5) + geom_smooth(method="glm", method.args=list(family="binomial")) |
如果已經將類別型變量映射到散點的顏色或形狀,則在添加擬合線時會分別為每一組添加一條擬合線。可以看到身高隨着年齡增長而增加,到一定年齡后停止增長,且男性比女性平均身高更高。
1 |
ggplot(heightweight, aes(x=ageYear, y=heightIn, color=sex)) + geom_point() + scale_color_brewer(palette="Set1") + geom_smooth() |
散點圖矩陣
散點圖矩陣用於展示多幅散點圖,pairs()函數可以創建基礎的散點圖矩陣,以下代碼包含mpg、disp、drat和wt中任意兩者的散點圖。
1 |
pairs(~ mpg + disp + drat + wt, data=mtcars, main="Basic Scatter Plot Matrix") |
car包的scatterplotMatrix()函數也可以生成散點圖矩陣,並支持以下操作:
- 以某個因子為條件繪制散點圖矩陣;
- 包含線型和平滑擬合曲線;
- 在主對角線放置箱線圖、密度圖或者直方圖;
- 在各單元格的邊界添加軸須圖。
1 2 |
library(car) scatterplotMatrix(~ mpg + disp + drat + wt, data=mtcars, spread=FALSE, lty.smooth=2, main="Scatter Plot Matrix via car Package") |
spread=FALSE選項表示不添加展示分散度和對稱信息的直線。
再來一個scatterplotMatrix()函數的使用例子,主對角線的核密度曲線改為了直方圖,並且直方圖以汽車氣缸數為條件繪制。
1 2 |
library(car) scatterplotMatrix(~ mpg + disp + drat + wt|cyl, data=mtcars, spread=FALSE, diagonal="histogram", main="Scatter Plot Matrix via car Package") |
gclus包中的cpairs()函數提供了一個有趣的散點圖矩陣變種,支持重排矩陣中變量的位置,讓相關性更高的變量更靠近主對角線,還可以對各單元格進行顏色編碼來展示變量間的相關性大小。
首先查看各個變量之間相關性的大小:
1 |
cor(mtcars[c("mpg", "wt", "disp", "drat")]) |
可以發現相關性最高(0.89)的是車重(wt)和排量(disp),以及車重(wt)和每加侖英里數(mpg)。相關性最低(0.68)的是每加侖英里數(mpg)和后軸比(drat)。以下代碼根據相關性大小,對散點圖矩陣中的這些變量重新排序並着色。
1 2 3 4 5 6 |
library(gclus) mydata <- mtcars[c(1,3,5,6)] mydata.corr <- abs(cor(mydata)) mycolors <- dmat.color(mydata.corr) myorder <- order.single(mydata.corr) cpairs(mydata, myorder, panel.colors=mycolors, gap=.5, main="Variables Ordered and Colored by Correlation") |
高密度散點圖
當散點圖中點數量過大時,數據點的重疊將會導致繪圖效果顯著變差。對於這種情況,可以使用封箱、顏色和透明度等來指定圖中任意點上重疊點的數目。
smoothScatter()函數可利用核密度估計生成用顏色密度來表示點分布的散點圖。
1 2 3 4 5 6 7 8 |
set.seed(1234) n <- 10000 c1 <- matrix(rnorm(n ,mean=0, sd=.5), ncol=2) c2 <- matrix(rnorm(n, mean=3, sd=2), ncol=2) mydata <- rbind(c1, c2) mydata <- as.data.frame(mydata) names(mydata) <- c("x", "y") smoothScatter(mydata$x, mydata$y, main="Scatterplot Colored by Smoothed Densities") |
hexbin包中的hexbin()函數將二元變量的封箱放到六邊形單元格中。
1 2 3 |
library(hexbin) bin <- hexbin(mydata$x, mydata$y, xbins=50) plot(bin, main="Hexagonal Binning with 10000 Observations") |
IDPmisc包中的iplot()函數也可以通過顏色來展示點的密度。
1 2 |
library(IDPmisc) iplot(mydata$x, mydata$y, main="Image Scatter Plot with Color Indicating Density") |
三維散點圖
如果想一次性對三個定量變量的交互進行可視化,那么可以使用scatterplot3d中的scatterplot3d()函數進行繪制。
1 2 3 4 |
library(scatterplot3d) attach(mtcars) scatterplot3d(wt, disp, mpg, main="Basic 3D Scatter Plot") detach(mtcars) |
scatterplot3d()函數提供了許多選項,包括設置圖形符號、軸、顏色、線條、網格線、突出顯示和角度等功能。例如以下代碼生成一幅突出顯示效果的三維散點圖,增強了縱深感並添加了連接點與水平面的垂直線。
1 2 3 4 |
library(scatterplot3d) attach(mtcars) scatterplot3d(wt, disp, mpg, pch=16, highlight.3d=TRUE, type="h", main="3D Scatter Plot with Vertical Lines") detach(mtcars) |
還可以再加上一個回歸面。
1 2 3 4 5 6 |
library(scatterplot3d) attach(mtcars) s3d <- scatterplot3d(wt, disp, mpg, pch=16, highlight.3d=TRUE, type="h", main="3D Scatter Plot with Vertical Lines and Regression Plane") fit <- lm(mpg ~ wt + disp) s3d$plane3d(fit) detach(mtcars) |
使用rgl包中的plot3d()函數可創建交互式的三維散點圖,通過鼠標即可對圖形進行旋轉。
1 2 3 4 |
library(rgl) attach(mtcars) plot3d(wt, disp, mpg, col="red", size=5) detach(mtcars) |
Rcmdr包中的scatter3d()函數可以實現類似功能。
1 2 3 4 |
library(Rcmdr) attach(mtcars) scatter3d(wt, disp, mpg) detach(mtcars) |
7 添加文本標注
使用geom_text()為散點圖添加標注,vjust為0時表示豎直方向上基線對齊,為1時表示頂部對齊,hjust為0時表示水平方向上左對齊,為1時表示右對齊,以下設置對齊方式並適當添加偏移,以改善顯示效果。
1 |
ggplot(subset(countries, Year==2009 & healthexp>2000), aes(x=healthexp, y=infmortality)) + geom_point() + geom_text(aes(y=infmortality+.1, label=Name), size=4, vjust=0) |
8 使用氣泡圖繪制二維統計
以下使用散點圖繪制氣泡圖,對兩個類別型變量進行統計。
1 2 3 4 |
hec <- HairEyeColor[,,"Male"] + HairEyeColor[,,"Female"] library(reshape2) hec <- melt(hec, value.name="count") ggplot(hec, aes(x=Eye, y=Hair)) + geom_point(aes(size=count), shape=21, color="black", fill="cornsilk") + scale_size_area(max_size=20, guide=FALSE) + geom_text(aes(y=as.numeric(Hair)-sqrt(count)/22, label=count), vjust=1, color="grey60", size=4) |
value1 <- rep(c('高價值','中價值','低價值'), each = 3)
value2 <- rep(c('高價值','中價值','低價值'), times = 3)
nums <- c(500,287,123,156,720,390,80,468,1200)
df <- data.frame(value1 = value1, value2 = value2, nums = nums)
df$value1 <- factor(df$value1, levels = c('高價值','中價值','低價值'), order = TRUE)
df$value2 <- factor(df$value2, levels = c('低價值','中價值','高價值'), order = TRUE)
ggplot(df,aes(x = value1, y = value2, size = nums)) +geom_point(colour = 'steelblue') +
scale_size_area(max_size = 30, guide = FALSE) +geom_text(aes(label = nums), vjust = 0, colour = 'black', size = 5) + theme(text = element_text(family = 'SimSun'))
繪制氣泡圖也可使用函數symbols(x,y,circle=r).當中x、y是坐標軸,r是每一個點的半徑。
x<-rnorm(6)
y<-rnorm(6)
r<-abs(rnorm(6))
symbols(x,y,circle = r, bg=rainbow(6))
###############氣泡圖例子2
attach(mtcars) # 激活或掛接數據集
#attach( )函數是將數據框添加到R的搜索路徑中 # mtcars為R語言內置數據集
r<-sqrt(disp/pi)
symbols(wt,mpg,circle=r, inches=0.3, bg="lightblue")
text(wt,mpg,row.names(mtcars), cex=0.5) #給每一個氣泡加上文字。
Chap6. 描述數據分布
數據分布可視化方法
直方圖
geom_histogram()
binwidth
設置組距;origin
設置分組原點- 各分組區間左閉右開
- 分面:
facet_grid(x ~.)
- 修改分類標簽:
revalue(x, c("0"="No smoke","1"="smoke"))
- 參數
scales = free
可以單獨設定各個分面的Y軸標度。
- 修改分類標簽:
我們經常想觀察一批數據的分布形態,直方圖、密度圖、箱線圖、小提琴圖和點圖等都是很好的實現形式。在此,我們簡略介紹直方圖、密度圖和箱線圖,這種三種圖形對我們來說更為常用。
直方圖
很多人沒搞清楚條形圖和直方圖之間的區別。條形圖主要用於展示分類數據,即名義數據,各組分開而立。而直方圖多用於展示數值型數據,各組相依。
單組直方圖
最基本的語句就是在ggplot語句后再加geom_histogram()即可。
-
library(gcookbook)
-
library(ggplot2)
-
ggplot(faithful, aes(x=waiting)) + geom_histogram(bins= 10)
直方圖默認最大為30組,我們可以使用*binwidth來改變。
ggplot(faithful, aes(x=waiting)) +geom_histogram(binwidth=8, bins=10,fill="white", colour="black")#改為8組
分組直方圖
分組直方圖做法與其他圖形一樣,我們用到facet_grid(var ~ .),該方法是以var變量進行分類,做多個圖形,非一個圖形中做多個直方圖。如果變量為數字,應當因子化。
-
library(MASS) #取binwidth數據
-
ggplot(birthwt, aes(x=bwt))+geom_histogram(fill= "white",bins=10, colour="black")+facet_grid(smoke ~ .)
核密度曲線
geom_line(stat='identity')
或者geom_density()
如果你想要做密度曲線,則用geom_density映射一連續變量。
-
ggplot(faithful, aes( x=waiting)) + geom_density()
-
#你也可以將包住的部分給填充顏色
-
ggplot(faithful, aes( x=waiting)) +
-
geom_density(fill= "blue", alpha=.2) +
-
xlim( 35, 105)
-
#如果你不喜歡線與下方相連,可以使用另外一種方式
-
ggplot(faithful, aes( x=waiting)) + geom_line(stat="density") +
-
expand_limits( y=0)#expand_limits使y軸范圍包含0值。
-
#密度曲線與直方圖共戲
-
ggplot(faithful, aes( x=waiting, y=..density..)) +
-
geom_histogram(fill= "cornsilk", colour="grey60", size=.2) +
-
geom_density() +
-
xlim( 35, 105)
分組密度曲線
-
library(MASS) #取binwidth數據
-
ggplot(birthwt, aes(x=bwt))+geom_histogram(fill= "white", colour="black")+facet_grid(smoke ~ .)
-
birthwt1 <- birthwt
-
birthwt1$smoke <- factor(birthwt1$smoke)
-
ggplot(birthwt1, aes(x=bwt, fill=smoke)) + geom_density(alpha= .3)
頻數多邊形
geom_freqpoly()
頻數多邊形描述了數據本身的信息,而核密度曲線只是一個估計,需要認為輸入帶寬參數。
箱線圖
geom_boxplot()
- 參數:
width
,outlier.size
,outlier.shape
- 添加槽口(notch):用來幫助查看不同分布的中位數是否有差異。
- 添加均值:
geom_summary(fun.y="mean",geom="point"...)
library(MASS) #取binwidth數據
ggplot(birthwt, aes(x=bwt))+geom_histogram(fill="white", colour="black")+facet_grid(smoke ~ .)
-
ggplot(birthwt, aes(x=factor(race), y=bwt)) + geom_boxplot()
-
#如果存在多個多個離群點,可用outlier.size 和outlier.shape進行大小和形狀設置
-
ggplot(birthwt, aes(x=factor(race), y=bwt)) +
-
geom_boxplot(outlier.size= 1.5, outlier.shape=21)
-
#為了看數據分布是否有偏,我們還可以增加均值與中值進行比較,主要用stat_summary把均值以菱形相展示。
-
ggplot(birthwt, aes(x=factor(race), y=bwt)) + geom_boxplot() +
-
stat_summary( fun.y="mean", geom="point", shape=23, size=3, fill="white")
小提琴圖
geom_violin()
- 小提琴圖用來比較多組數據分布情況的方法,其也是核密度估計。
- 坐標范圍:從最小值到最大值,與箱線圖不同。
- 參數:
adjust
調整平滑程度,scale="count"
使得圖的面積與每組觀測值數目成正比。
p = ggplot(data=mpg, mapping=aes(x=class, y=hwy, fill=class))
p + geom_boxplot() + geom_jitter(shape=21)
p + geom_violin(alpha=0.5, width=0.9) + geom_jitter(shape=21)
Wilkinson點圖
geom_dotplot()
- Wilkinson點圖:沿着x軸方向對數據進行分組,並在y軸上對點進行堆積。圖形上Y軸的刻度線沒有明確的含義。
- 備注:移除刻度線
scale_y_continuous(break=NULL)
,移除坐標軸標簽theme(axis.title.y=element_blank())
- 參數
binaxis=”y”
,將數據點沿着Y軸進行堆疊,並沿着x軸分組。stackdir="center"
:中心堆疊
p = ggplot(data=mpg, mapping=aes(x=class, y=hwy, fill=class))
p +geom_dotplot()
顏色圖和等高圖
par(mar = rep(1, 4))
x = 10 * (1:nrow(volcano))
y = 10 * (1:ncol(volcano))
image(x, y, volcano, col = terrain.colors(100), axes = FALSE)
contour(x, y, volcano, levels = seq(90, 200, by = 5),add = TRUE, col = "peru")
box()
極坐標 (玫瑰圖)
dt = data.frame(A = c(2, 7, 4, 10, 1,5), B = c('B','A','C','D','E','B'))
windowsFonts(myFont = windowsFont("楷體")) ## 綁定字體
p = ggplot(dt, aes(x = B, y = A, fill = B)) + geom_bar(stat = "identity", alpha = 0.7) + coord_polar()
p
Chap7. 注解
文本注解
geom_text()
annotate()
:可以添加任意類型的幾何對象。annotate("text",x=,y=,label=,...)
數學表達式
annotate("text",...,parse=TRUE,...)
- 引入常規文本:在雙引號內使用單引號標出純文本的部分即可。
- 不能簡單地把一個變量之間放到另一個變量旁邊卻不在中間添加任何記號。
?plotmath
和?demo(plotmath)
添加直線
- 橫線和豎線:
geom_hline(yintercept=)
&geom_vline()
- 有角度的直線:
geom_abline(intercept=,slope=)
添加線段和箭頭
- 線段:
annotate("segment",x=,xend=,y=,yend=)
- 利用grid包中的
arrow()
函數向線段兩端添加箭頭或平頭。
添加矩形陰影
annotate("rect",xmin=,xmax=,ymin=,ymax=,alpha=,fill=)
添加誤差線
geom_errorbar(aes(ymin=,ymax=),width=,position=)
向獨立分面添加注解
-
-
p <- ggplot(mpg, aes(x=displ,y=hwy)) +
-
geom_point() + facet_grid(.~drv)
-
-
f_labels <- data.frame(drv=c( "4","f","r"),
-
label=c( "4wd","Front","Rear"))
-
p + geom_text(x= 6,y=40,aes(label=label), data= f_labels) 1. `sprintf()`:returns a character vector containing a formatted combination of text and variable values. 2. `sprintf("italic(y) == %.2f %+.2f * italic(x)",round(coef(mod)[1],2),round(coef(mod)[2],2))`
1 添加文本注解
使用annotate()生成一條文本注解,通過x和y指定文本位置,可以是具體數值或者Inf和-Inf,表示圖形的邊緣,使用hjust和vjust進行水平方向和豎直方向上的微調,使用family、color、size分別指定字體、顏色、大小。
1 |
ggplot(faithful, aes(x=eruptions, y=waiting)) + geom_point() + annotate("text", x=3, y=48, label="Group 1", family="serif", color="darkred", size=5) + annotate("text", x=mean(range(faithful$eruptions)), y=-Inf, label="Group 2", vjust=-1) |
2 添加數學表達式
還是使用annotate(),不過需要制定parse為TRUE,表示對文本進行公式解析。
1 |
ggplot(data.frame(x=c(-3, 3)), aes(x=x)) + stat_function(fun=dnorm) + annotate("text", x=0, y=0.05, parse=TRUE, size=4, label="'Function: ' * y==frac(1, sqrt(2*pi)) * e^{-x^2/2}") |
更多和公式語法有關的內容可參考?plotmath,更多數學表達式的圖示可參考?demo(plotmath)。
3 添加直線
使用geom_hline()、geom_vline()、geom_abline()分別繪制水平線、豎直線和有角度的線。如果x軸或y軸為類別型變量,則第一個水平為數值1,第二個水平為數值2,依此類推。
1 2 |
library(gcookbook) ggplot(heightweight, aes(x=ageYear, y=heightIn, color=sex)) + geom_point() + geom_hline(yintercept=60) + geom_vline(xintercept=14) + geom_abline(intercept=37.4, slope=1.75) |
同樣可以通過指定類別型變量繪制多條直線。
1 2 3 |
library(plyr) hw_means <- ddply(heightweight, "sex", summarise, heightIn=mean(heightIn)) ggplot(heightweight, aes(x=ageYear, y=heightIn, color=sex)) + geom_point() + geom_hline(aes(yintercept=heightIn, color=sex), data=hw_means, linetype="dashed", size=1) |
4 添加線段和箭頭
在annotate()中指定segment可以添加線段,還可以為線段添加箭頭,箭頭默認角度angle為30度,默認長度length為0.2英寸,使用x、xend、y、yend指定線段的起始位置。如果x軸或y軸為類別型變量,則相應地第一個水平使用數值1,第二個水平使用數值2,依次類推。
1 2 |
library(grid) ggplot(subset(climate, Source=="Berkeley"), aes(x=Year, y=Anomaly10y)) + geom_line() + annotate("segment", x=1850, xend=1820, y=-.8, yend=-.95, color="blue", size=2, arrow=arrow()) + annotate("segment", x=1950, xend=1980, y=-.25, yend=-.25, arrow=arrow(ends="both", angle=90, length=unit(.2, "cm"))) |
5 添加矩形陰影
在annotate()中指定rect可以添加矩形,其實只要傳遞了合適的參數,任意幾何對象都可以配合annotate()使用。
1 2 |
library(gcookbook) ggplot(subset(climate, Source=="Berkeley"), aes(x=Year, y=Anomaly10y)) + geom_line() + annotate("rect", xmin=1950, xmax=1980, ymin=-1, ymax=1, alpha=.1, fill="blue") |
6 向獨立分面添加注解
使用分面變量生成一個新的數據框,並設定每個分面要繪制的值,然后配合新數據框使用geom_text()。
1 2 3 |
p <- ggplot(mpg, aes(x=displ, y=hwy)) + geom_point() + facet_grid(.~drv) f_labels <- data.frame(drv=c("4", "f", "r"), label=c("4wd", "Front", "Rear")) p + geom_text(x=6, y=40, aes(label=label), data=f_labels) |
再來一個為每個分面添加擬合直線公式的例子。
1 2 3 4 5 6 7 8 9 10 |
lm_labels <- function(dat) { mod <- lm(hwy ~ displ, data=dat) formula <- sprintf("italic(y) == %.2f%+.2f * italic(x)", round(coef(mod)[1], 2), round(coef(mod)[2], 2)) r <- cor(dat$displ, dat$hwy) r2 <- sprintf("italic(R^2) == %.2f", r^2) data.frame(formula=formula, r2=r2, sringAsFactors=FALSE) } library(plyr) labels <- ddply(mpg, "drv", lm_labels) ggplot(mpg, aes(x=displ, y=hwy)) + geom_point() + facet_grid(.~drv) + geom_smooth(method=lm, se=FALSE) + geom_text(x=3, y=40, aes(label=formula), data=labels, parse=TRUE, hjust=0) + geom_text(x=3, y=35, aes(label=r2), data=labels, parse=TRUE, hjust=0) |
Chap8. 坐標軸
交換x軸和y軸
-
coord_filp()
-
# x是因子型變量
-
+ scale_x_discrete(limits=rev(levels(..)))
坐標軸的值域
ylim()
或者xlim()
- 全稱:
scale_y_continuous(limits=c(,),breaks=c(.,.,.))
- 注意區分
scale_y_continuous()
和coord_cartesian()
;其中前者表示使用標度限制y到更小的范圍,范圍外的數據被丟棄,而后者則是利用坐標變換放大或縮小了數據。 expand_limits()
:只能用來擴展數據,而不能用來縮減值域。
反轉一條連續型坐標軸
-
scale_y_reverse()
-
scale_x_reverse()
修改類別型坐標軸上項目的順序
-
scale_x_discrete(limits=c(.,.,.))
-
# 反轉坐標軸
-
scale_x_discrete(limits=rev(levels(...)))
設置x軸和y軸的縮放比例
coord_fixed(ratio=1)
默認情況下,ggplot2使兩軸的總長寬比例為1:1,從而形成正方形的繪圖區域,而本節中所提到的比例為:坐標軸單位長度表示的數值范圍
設置刻度線的位置
參數breaks
離散型變量的坐標軸:設置limits
以重排序或移除項目,而設置breaks
來控制哪些項目擁有標簽。
移除刻度線和標簽
-
# 移除刻度標簽
-
theme(axis.text.y = element_blank())
-
# 移除刻度線
-
theme(axis.ticks = element_blank())
-
# 同時移除連續型變量的刻度線、刻度標簽和網格線
-
scale_y_continuous(breaks= NULL) 刻度標簽可以單獨控制,但是刻度線和網格線必須同時控制。
修改刻度標簽的文本
參數:breaks & labels
package:scales自帶了一些內置的格式化函數,比如comma(),dollar(),percent(),scientific()
修改刻度標簽的外觀
-
-
theme(axis. text.x = element_text(angle=90,hjust=,vjust=))
-
-
theme(axis. text.x = element_text(family=,face=,colour=,size=rel()))
-
rel( 0.9):表示為當前主題基礎字體大小的0.9倍
修改坐標軸標簽的文本
-
# 簡便法
-
xlab() & ylab()
-
# 完整法
-
scale_x_continuous(name= "") 文本中可包含`\n,\t`等文本符號
移除坐標軸標簽
theme(axis.title.x = element_blank())
對數坐標軸
-
scale_x_log10() & scale_y_log10()
-
# 刻度標簽轉而使用指數計數法
-
library(scales)
-
scale_x_log10(breaks= 10^(-1:5), labels=trans_format("log10",math_format(10^.x)))
-
# 自然對數
-
trans=log_trans()
-
# 以2為底的對數
-
trans = log2_trans()
對數坐標軸添加刻度
annotation_logticks()
坐標軸上使用日期
-
library(scales)
-
# Date 對象
-
p + scale_x_time(breaks = datebreaks, date_format( "%Y-%m"))
-
# POSIXt對象
-
p + scale_x_datetime(breaks = datebreaks,date_format())
-
+ theme(axis.text.x = element_text(angle= 90, hjust=1))
1 交換X軸和Y軸
使用coord_flip()來翻轉坐標軸。
1 |
ggplot(PlantGrowth, aes(x=group, y=weight)) + geom_boxplot() + coord_flip() |
2 設置連續型坐標軸的值域
可以使用xlim()和ylim()來設置連續型坐標軸的最小值和最大值。
1 |
ggplot(PlantGrowth, aes(x=group, y=weight)) + geom_boxplot() + ylim(0, max(PlantGrowth$weight)) |
ylim()是scale_y_continuous()的簡化寫法,后者還可以使用breaks設置刻度線的位置。
1 2 |
ylim(0, 10) scale_y_continuous(limits=c(0, 10), breaks=c(0, 5, 10)) |
3 反轉連續型坐標軸
使用scale_y_reverse()和scale_x_reverse()反轉連續型坐標軸。
4 修改類別型坐標軸上項目的順序
通過scale_x_discrete()和scale_y_discrete()並將一個依所需順序排列的水平向量傳遞給limits即可。如果在limits中省略某一類別對應的值,則該類別在繪圖中將不顯示。
1 |
ggplot(PlantGrowth, aes(x=group, y=weight)) + geom_boxplot() + scale_x_discrete(limits=c("trt1", "ctrl", "trt2")) |
以下代碼反轉類別型坐標軸的項目順序。
1 |
ggplot(PlantGrowth, aes(x=group, y=weight)) + geom_boxplot() + scale_x_discrete(limits=rev(levels(PlantGrowth$group))) |
5 設置X軸和Y軸的縮放比例
當x軸和y軸所對應的連續型變量具有相同的尺度和量級時,可以通過coord_fixed()使得x軸和y軸之間保持1:1的縮放結果。
1 2 |
library(gcookbook) ggplot(marathon, aes(x=Half, y=Full)) + geom_point() + coord_fixed() |
如果希望使用其他縮放比例時,在coord_fixed()中指定ratio即可。
1 |
ggplot(marathon, aes(x=Half, y=Full)) + geom_point() + coord_fixed(ratio=1/2) |
6 修改刻度標簽的文本
在需要設置刻度標簽的地方同時為breaks和labels賦值即可。
1 2 |
library(gcookbook) ggplot(heightweight, aes(x=ageYear, y=heightIn)) + geom_point() + scale_y_continuous(breaks=c(50, 56, 60, 66, 72), labels=c("Tiny", "Really\nshort","Short", "Medium", "Tallish")) |
也可以定義一個格式化函數,將原始的值自動地轉換為相應的標簽。
1 2 3 4 5 6 7 |
# 將英寸轉換為英尺加英寸 footinch_formatter <- function(x) { foot <- floor(x/12) inch <- x %% 12 return(paste(foot, "'", inch, "\"", sep="")) } ggplot(heightweight, aes(x=ageYear, y=heightIn)) + geom_point() + scale_y_continuous(labels=footinch_formatter) |
scales包提供了一些常用的格式化函數:
- comma(),在千、百萬、十億等位置向數字添加逗號;
- dollar(),添加一個美元符號並舍入到最接近的美分;
- percent(),乘以100,舍入到最接近的整數值,並添加一個百分號;
- scientific(),對大數字和小數字給出科學計數法表示。
除此之外,通過ggplot2提供的theme()可以對刻度標簽文本設置字體、樣式、大小和顏色,進行旋轉和平移等操作,當然還包括對坐標軸標簽文本、標題、圖例等全部元素的樣式自定義,詳情請參考?theme。
7 修改標題和坐標軸標簽文本
使用labs()可以同時設置x軸標簽、y軸標簽和標題,如果使用到了中文,還需要用theme()設置全局字體,參考這里。
1 |
labs(x="x軸標簽", y="y軸標簽", title="繪圖標題") |
8 使用對數坐標軸
使用scale_x_log10()和scale_y_log10()可以將線性坐標軸轉換為對數坐標軸,在某些情況下,使用對數坐標軸更有意義。
1 2 |
library(MASS) ggplot(Animals, aes(x=body, y=brain, label=rownames(Animals))) + geom_text(size=3) + scale_x_log10() + scale_y_log10() |
9 繪制極坐標
使用coord_polar()即可繪制極坐標。
1 2 |
library(gcookbook) ggplot(wind, aes(x=DirCat, fill=SpeedCat)) + geom_histogram(binwidth=15, boundary=-7.5) + coord_polar() + scale_x_continuous(limits=c(0, 360)) |
然而,由於極坐標的原因,扇形大小並不能直觀反映出實際的觀測數量,而且多種顏色混雜難以讓人對風力有直觀的感受,因此我們需要改變一下樣式。
1 |
ggplot(wind, aes(x=DirCat, fill=SpeedCat)) + geom_histogram(binwidth=15, boundary=-7.5, color="black", size=.2) +guides(fill=guide_legend(reverse=TRUE)) + coord_polar() + scale_x_continuous(limits=c(0, 360), breaks=seq(0, 360, by=45), minor_breaks=seq(0,360, by=15)) + scale_fill_brewer() |
Chap9.控制圖形的整體外觀
設置圖形標題
-
-
ggtitle()
-
labs(title= "")
-
-
annotate( "text",x=mean(range(x)),y=Inf,label="Age",vjust=1.5,size=6)
修改文本外觀
文本項目分為兩類:主題元素和文本幾何對象。主題元素包括圖形中的所有非數據元素:如標題、圖例和坐標軸。文本幾何對象則屬於圖形本身的一部分。
- family: Helvatica、Times、Courier
- face: plain、bold、italic、bold.italic
- lineheight: 行間距倍數
- angle: 旋轉角度(逆時針)
- size: 字體大小(主題為磅,幾何對象為毫米)
- strip.text: 雙向分面標簽的外觀
使用主題
-
# 預制的主題:
-
theme_bw()
-
theme_grey()
-
# 設置默認主題
-
theme_set(theme_bw())
## 修改主題元素的外觀
要修改一套主題,配合相應的element_xx
對象添加theme()
函數即可。element_xx
對象包括element_line
、element_rect
和element_text
。
創建自定義主題
-
mytheme = theme_bw() +
-
theme( text = element_text(colour="red"),axis.title=element_text(size=rel(1.25)))
-
p + mytheme
隱藏網格線
- 主網格線:panel.grid.major
- 次網格線:panel.grid.minor
Chap10. 圖例
像x軸和y軸一樣,圖例也是一種引導元素:它可以向人們展示如何從視覺上的圖形屬性映射回數據本身。
-
-
guides(fill= FALSE)
-
-
theme(legend.position= "bottom")
-
-
theme(legend.position=c( 1,0)) +
-
theme(legend.bakground=element_rect(fill= "white",colour="black"))
-
-
scale_fill_discrete(limits=c( "a","b","c"))
-
-
guides(fill=guide_legend(reverse= TRUE))
-
-
labs(fill= "Condition")
-
guides(fill=guide.legend(title= "Condition"))
-
-
theme(legend.title=element_text(face= "italic",family="Times",colour="red",size=14))
-
-
scale_fill_discrete(limits=c( "a","b","c"),labels=c("A","B","C"))
-
-
theme(legend. text=element_text(xx))
-
-
library(grid)
-
-
theme(legend. text=element_text(lineheight=0.8),legend.key.height=unit(1,"cm"))
Chap11. 分面
數據可視化中最實用的技術之一就是將分組數據並列呈現,這樣使得組間的比較變得輕而易舉。
-
-
facet_grid(. ~ cyl,scale= "free")
-
facet_wrap(~ class, nrow=2)
-
-
theme(strip. text=element_text(face="bold",size=rel(1.5)),strip.background=element_rect(fill="lightblue",colour="black",size=1))
即在一個頁面上自動擺放多幅圖形, 這一過程先將數據划分為多個子集, 然后將每個子集依次繪制到頁面的不同面板中。ggplot2提供兩種分面類型:網格型(facet_grid)和封面型(facet_wrap)。網格分面生成的是一個2維的面板網格, 面板的行與列通過變量來定義, 本質是2維的; 封裝分面則先生成一個1維的面板條塊, 然后再分裝到2維中, 本質是1維的。
在很多情況下, 我們可能需要繪制有兩個y軸的坐標系, 而在ggplot2中, 這種做法特別不提倡(stackover的討論), 可解決的方法要么是把變量歸一化, 要么便是采用分面方法。
p <- ggplot(mtcars, aes(mpg, wt, colour = cyl)) +geom_point() #geom_point()為通過”+”以圖層的方式加入點的幾何對象
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p + facet_grid(. ~ cyl) #以cyl為分類變量
p + facet_wrap( ~ cyl, nrow = 3) #wrap與grid的區別
p + facet_grid(cyl ~ .) #以cyl為分類變量
p + facet_wrap( ~ cyl, ncol = 3) #wrap與grid的區別
p + facet_grid(vs ~ am) #以vs和am為分類變量
p + facet_wrap(vs ~ am, ncol = 2) #wrap與grid 的區別
Chap12. 配色
離散型變量調色板
- 等距色:scale_fill_discrete()
- 色輪等距色:scale_fill_hue()
- 灰度調色板:scale_fill_grey()
- 調色板顏色:scale_fill_brewer()
- 自定義顏色:scale_fill_manual()
-
# 設置亮度參數(Default:l=65)
-
scale_fill_hue(l= 45)
-
# 調用調色板
-
library(RColorBrewer)
-
display.brewer.all()
-
# 使用自定義調色板
-
scale_fill_manual( values=mycol)
對類別型數據中的點而言,最好選擇調色板Set1
和Dark2
;對面積而言,Set2
、Pastel1
、Pastel2
和Accent
都是不錯的選擇方案。
RGB顏色
RGB顏色是由六個數字組成(十六進制數),形式如“#RRGGBB”。在十六進制中,數字先從0到9,然后緊接着是A到F。每一個顏色都由兩個數字表示,范圍從00到FF。比如顏色“#FF0099”中,255表示紅色,0表示綠色,153表示藍色,整體表示品紅色。十六進制數中每個顏色通道常常重復同樣的數字,因子這樣更容易閱讀並且第二個數字的精確值對外觀的影響並不是很明顯。
RGB經驗法則
- 一般情況下,較大的數字更明亮,較小的數字更暗淡。
- 如果要得到灰色,將三個顏色通道設置為相同的值。
- CMY(印刷三原色):青(cyan)、品紅(magenta)、黃(yellow)。
- RGB顏色
色盲友好式調色板
-
cb_col = c( "#000000","#E69F00","#56B4E9","#009E73","#F0E442","#0072B2","#D55E00","#CC79A7")
-
scale_fill_manual( values=cb_col)
-
# 調用dichromat包
連續型變量調色板
- 兩色漸變:scale_fill_gradient()
- 三色漸變:scale_fill_gradient2()
- 等間隔n色漸變:scale_fill_gradientn()
Chap15. 其他圖形
相關矩陣圖
-
library(corrplot)
-
corrplot(cor(x),method= "shade",shade.col=NA,tl.col="black",tl.srt=45,col=col(200),addCoef.col="black",cl.pos="no",order="AOE")
繪制函數曲線
-
# 函數曲線
-
stat_function( fun=myfun, n=200)
-
# 函數曲線下添加陰影
-
## 定義一個新函數,把x范圍外的值替換為NA
-
p + stat_function( fun=myfun, geom="area", fill="blue",alpha=0.2) +
-
stat_function( fun=myfun)
-
# 繪制經驗累積分布函數圖
-
stat_ecdf()
繪制熱圖
使用geom_tile()
或者geom_raster()
,並將一個連續變量映射到fill上。
-
p + geom_tile() +
-
scale_x_continuous(breaks = se q(1940,1976,by=4)) +
-
scale_y_reverse() +
-
scale_fill_gradient2(midpoint= 50,mid="grey70",limits=c(0,100))
三維散點圖
-
library(rgl)
-
# 繪制點
-
plot3d(x,y,z,type= "s",size=0.75,lit=FALSE)
-
# 添加線段
-
interleave = function(v1,v2) as.vector(rbind(v1,v2))
-
segment3d(interleave(x,x),
-
interleave(y,y),interleave(z,min(z)),alpha=0.4,col="blue")
-
# 繪制盒子
-
rgl.bbox(color="grey50", emission="grey50",xlen=0,ylen=0,zlen=0)
-
# 保存圖像
-
rgl.snapshot("3dplot.png", fmt="png")
-
rgl.postscript("3dplot.pdf",fmt="pdf")
-
# 三維圖動畫
-
plot3d(x,y,z,type="s",size=0.75,lit=FALSE)
-
play3d(spin3d())
-
movie3d(spin3d(axis=c(1,0,0),rpm=4),duration=15,fps=50)
-
繪制譜系圖
-
hc = hclust(scale(x))
-
plot(hc, hang=-1)
繪制QQ圖
-
# base畫圖
-
qqnorm( x)
-
qqline( x)
-
# ggplot2畫圖
-
predicted <- data.frame(i = 1:length(VALUE), x=1:length(VALUE), y=1:length(VALUE))
-
predicted$x <- qnorm((predicted$i- 0.375)/(nrow(predicted+0.25)))
-
predicted$y <- sd(VALUE)*predicted$x+mean(VALUE)
-
ggplot(data.frame(VALUE), aes(sample = VALUE)) +
-
stat_ qq() +
-
geom_line(data=predicted[,- 1],aes(x=x,y=y),size=1,colour="red")
繪制臉型圖
#可以利用函數cbind() 和rbind() 把向量和矩陣拼成一個新的矩陣
library(TeachingDemos)
data <- rbind(c(80394, 32903, 13.2),
c(82560, 36230, 13.8),
c(85213, 26921, 10.8))
faces2(data, which = c(3, 14, 12), labels = c("北京", "上海", "天津"), ncols = 3)
繪制馬賽克圖
-
# 主要用來可視化列聯表
-
library(vcd)
-
mosaic(~x+y+z, data, highlighting= "x",highlighting_fill=c(lightblue","pink"),direction=c("v","h","v"))
-
繪制餅圖
-
fold = table(survey$ Fold)
-
pie(fold,labels= c("x","y","z"))
繪制地圖
Chap14. 保存圖形
Web瀏覽器更支持SVG文件,而LaTeX則更支持PDF文件。
輸出為PDF矢量文件
-
#width和height的單位為英寸
-
pdf( "myplot.pdf",width=4,height=4,useaDingbats=FALSE)
-
plot(x,y)
-
print(ggplot(data,aes(x=x,y=y))+geom_point())
-
dev.off()
-
# 如果圖形多於一幅,則每一幅將在PDF輸出中列於獨立的一頁。
-
# ggsave()不能用於創建多頁圖形
-
ggsave( "myplot.pdf",width=8,height=8,units="cm",useaDingbats=FALSE)
輸出為SVG矢量文件
-
svg( "myplot.svg",width=4,height=4)
-
plot()
-
dev. off()
輸出為WMF矢量文件
Windows圖元文件(WMF),即只能在Windows上創建。
-
win.metafile( "myplot.wmf",width=4,height=4)
-
plot()
-
dev. off()
-
-
ggsave( "myplot.wmf",width=8,height=8,units="cm")
輸出為點陣(PNG/TIFF)文件
-
png( "myplot.png",width=400,height=400)
-
plot(x,y)
-
dev. off()
-
-
png( "myplot-%d.png",width=400,height=400)
-
plot()
-
print(ggplot())
-
dev. off()
-
-
ggsave( "myplot.png",width=8,height=8,unit="cm",dpi=300)
-
-
install.packages( "Cairo")
-
CairoPNG( "myplot.png")
-
plot()
-
dev. off()
在圖中顯示中文
-
# MAC用戶
-
plot(x, main= "散點圖",xlab="數",ylab="值",family="SimSun")
-
ggplot(data, aes(x=x,y=y))+
-
geom_point()+
-
annotate( "text",x=10,y=30,size=10,label="我就是我!",family="SimSun")+
-
xlab( "數")+
-
ylab( "值")+
-
theme(title=element_text(family= "SimSun"))
一頁多圖
視圖窗口(viewport):顯示設備的一個矩陣子區域。grid.layout()
設置了一個任意高和寬的視圖窗口布局。
-
pdf( "myplot.pdf",width=8,height=6)
-
grid.newpage()
-
pushViewport(viewport(layout=grid.layout( 2,2)))
-
vplayout = function(x,y){
-
viewport(layout.pos.row=x, layout.pos.col=y)
-
}
-
print(a, vp = vplayout(1, 1:2))
-
print(b, vp = vplayout(2, 1))
-
print(c, vp = vplayout(2, 2))
-
dev.off()
默認的grid.layout()
中,每個單元格的大小都相同,可以設置widths
和heights
參數使得它們具有不同的大小。
時間序列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
地圖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
當然, 這只是簡單的地圖繪制方法,統計之都上也有很多大牛來用R繪制各種各樣精美的地圖(1, 2)。
劑量-效應曲線
R中的drc包很容易對各種劑量-效應曲線進行繪圖, 此處采用較為常用的log-logistic四參數方程擬合了劑量-效應曲線。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
現代線條藝術欣賞
1 羽毛圖
1 2 3 4 5 6 7 8 9 10 11 12 13 |
x1 = c(seq(0, pi, length = 50), seq(pi, 2*pi, length = 50)) y1 = cos(x1) / sin(x1) x2 = seq(1.02 * 2 * pi + pi/2, 4*pi + pi/2, length = 50) y2 = tan(x2) op = par(bg="black", mar=rep(.5,4)) plot(c(x1, x2), c(y1, y2), type = "n", ylim = c(-11, 11)) for (i in seq(-10, 10, length = 100)) { lines(x1, y1 + i, col = hsv(runif(1,.65,.7), 1, 1, runif(1,.7)), lwd = 4 * runif(1, 0.3)) lines(x2, y2 + i, col = hsv(runif(1,.65,.7), 1, 1, runif(1,.7)), lwd = 4 * runif(1, 0.3)) } |
2 心形圖
1 2 3 4 5 6 7 8 9 10 |
theta = seq(-2 * pi, 2 * pi, length = 300) x = cos(theta) y = x + sin(theta) op = par(bg = "black", mar = rep(0.1, 4)) plot(x, y, type = "n", xlim = c(-8, 8), ylim = c(-1.5, 1.5)) for (i in seq(-2*pi, 2*pi, length = 100)) { lines(i*x, y, col = hsv(runif(1, 0.85, 0.95), 1, 1, runif(1, 0.2, 0.5)), lwd = sample(seq(.5, 3, length = 10), 1)) } |
3 幻圈圖
1 2 3 4 5 6 7 8 9 10 |
theta = 1:100 x = sin(theta) y = cos(theta) op = par(bg = 'black', mar = rep(0.5, 4)) plot.new() plot.window(xlim = c(-1, 1), ylim = c(-1, 1), asp = 1) lines(x, y, col = hsv(0.65, 1, 1)) lines(0.8 * x, 0.8 * y, col = hsv(0.8, 1, 1)) lines(0.6 * x, 0.6 * y, col = hsv(0.9, 1, 1)) lines(0.4 * x, 0.4 * y, col = hsv(0.95, 1, 1)) |
4 土星環
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
x = seq(-50, 50, by = 1) y = -(x^2) op = par(bg = 'black', mar = rep(0.5, 4)) plot(y, x, type = 'n') lines(y, x, lwd = 2*runif(1), col = hsv(0.08, 1, 1, alpha = runif(1, 0.5, 0.9))) for (i in seq(10, 2500, 10)) { lines(y-i, x, lwd = 2*runif(1), col = hsv(0.08, 1, 1, alpha = runif(1, 0.5, 0.9))) } for (i in seq(500, 600, 10)) { lines(y - i, x, lwd = 2*runif(1), col = hsv(0, 1, 1, alpha = runif(1, 0.5, 0.9))) } for (i in seq(2000, 2300, 10)) { lines(y - i, x, lwd = 2*runif(1), col = hsv(0, 1, 1, alpha = runif(1, 0.5, 0.9))) } for (i in seq(100, 150, 10)) { lines(y - i, x, lwd = 2*runif(1), col = hsv(0, 1, 1, alpha = runif(1, 0.5, 0.9))) } |
5 字母印象
1 2 3 4 5 6 7 8 9 10 11 12 |
nx = 100 ny = 80 x = sample(x = 1:nx, size = 90, replace = TRUE) y = seq(-1, -ny, length = 90) op = par(bg = "black", mar = c(0, 0.2, 0, 0.2)) plot(1:nx, seq(-1, -nx), type = "n", xlim = c(1, nx), ylim = c(-ny+10, 1)) for (i in seq_along(x)) { aux = sample(1:ny, 1) points(rep(x[i], aux), y[1:aux], pch = sample(letters, aux, replace = TRUE), col = hsv(0.35, 1, 1, runif(aux, 0.3)), cex = runif(aux, 0.3)) } |
6 絢麗霞光
1 2 3 4 5 6 7 8 9 |
theta = seq(0, pi, length = 300) x = cos(theta) y = sin(theta) op = par(bg = "black", mar = rep(0.5, 4)) plot(x, y, type = 'n') segments(rep(0, 299), rep(0, 299), x[1:299] * runif(299, 0.7), y[1:299] * runif(299, 0.7), col = hsv(runif(299, 0.45, 0.55), 1, 1, runif(299, 0.5)), lwd = 5*runif(299)) |
作者:EasyCharts
鏈接:https://zhuanlan.zhihu.com/p/23414691
參考資料:
R語言_ggplot2:數據分析與圖形藝術
R數據可視化手冊
ggplot2繪制餅圖
ggplot2繪制散點圖
ggplot2實現多圖合並
基於ggplot2圖形的微調
https://my.oschina.net/935572630/blog/625401
http://www.itdadao.com/articles/c15a507013p0.html
https://zhuanlan.zhihu.com/p/23414691?refer=EasyCharts-R
即使只是凡世中一顆小小的塵埃,命運也要由自己主宰,像向日葵般,迎向陽光、勇敢盛開