R語言中ggplot2繪制雙坐標軸圖
R包ggplot2繪圖精美,可以做出很復雜的圖形,深受用戶喜愛。它的作者hadley并不推薦使用ggplot2繪制雙坐標軸圖,認為這樣會增加讀圖的難度,但是目前需要雙坐標軸圖應用的場景還是很多,如下圖形直方圖和曲線分別有不同的坐標軸,表示不同的意思,圖片展示內容比較豐富


今天我們通過我們的汽車銷售數(shù)據(jù)(公眾號回復:汽車銷售,可以獲得數(shù)據(jù))來演示一下ggplot2繪制雙坐標軸圖,主要是通過sec.axis函數(shù)進行轉換,進行第二個坐標軸的轉換。我們先來導入數(shù)據(jù)
library(foreign)
library(ggplot2)
library(plyr)
bc <- read.spss("E:/r/test/tree_car.sav",
use.value.labels=F, to.data.frame=T)

我們來看下數(shù)據(jù),car就是汽車售價,age是年齡,gender是性別,inccat是收入,這里分成4個等級,ed是教育程度。
我們用這個數(shù)據(jù)生成兩個子數(shù)據(jù),展示不同教育程度人群購車的區(qū)別,繼續(xù)使用原來的summarySE函數(shù)生成數(shù)據(jù),想了解這個函數(shù)的看《R語言繪制帶誤差和可信區(qū)間的折線圖》這篇文章,主要是利用這個函數(shù)生成不同類型的數(shù)據(jù)分析指標,函數(shù)的代碼如下:
summarySE <- function(data=NULL, measurevar, groupvars=NULL, na.rm=FALSE,
conf.interval=.95, .drop=TRUE) {
library(plyr)
# New version of length which can handle NA's: if na.rm==T, don't count them
length2 <- function (x, na.rm=FALSE) {
if (na.rm) sum(!is.na(x))
else length(x)
}
# This does the summary. For each group's data frame, return a vector with
# N, mean, and sd
datac <- ddply(data, groupvars, .drop=.drop,
.fun = function(xx, col) {
c(N = length2(xx[[col]], na.rm=na.rm),
mean = mean (xx[[col]], na.rm=na.rm),
sd = sd (xx[[col]], na.rm=na.rm)
)
},
measurevar
)
# Rename the "mean" column
datac <- rename(datac, c("mean" = measurevar))
datac$se <- datac$sd / sqrt(datac$N) # Calculate standard error of the mean
# Confidence interval multiplier for standard error
# Calculate t-statistic for confidence interval:
# e.g., if conf.interval is .95, use .975 (above/below), and use df=N-1
ciMult <- qt(conf.interval/2 + .5, datac$N-1)
datac$ci <- datac$se * ciMult
return(datac)
}
這個函數(shù)并不是今天的主要內容,主要是看我們生成的數(shù)據(jù)
carss<- summarySE(bc, measurevar="car", groupvars=c("gender","ed"))
carss1<- summarySE(bc, measurevar="car", groupvars=c("inccat","ed"))
我們來看看生成的兩個數(shù)據(jù)
Carss

carss1

carss1和carss都有ed這個數(shù)據(jù),carss1的數(shù)據(jù)比carss多,carss1有inccat這個指標carss沒有
我們先畫一個carss數(shù)據(jù)的教育和汽車售價的直方圖
ggplot() + geom_col( data = carss,aes(x = ed,y = car),fill="#6794a7")

上圖展示了不同教育程度買車的情況,假設我們想把carss1這個數(shù)據(jù)的inccat和ci這個指標映射進上圖中(不管臨床意義,只是展示數(shù)據(jù)映射),我們可以看到ci這個指標很小0-5這樣,而汽車這個指標的范圍是0-80,不能通過同一坐標軸展示,所以只能通過分軸展示。主要是通過rescale函數(shù)先把ci這個指標在在0-80區(qū)間進行標準化轉換,然后在投射于右坐標軸。
先把inccat轉換成因子
carss1$inccat<-as.factor(carss1$inccat)
繪圖
ggplot() +
geom_col( data = carss,aes(x = ed,y = car),fill="#6794a7")+
geom_line(data = carss1,aes(x = ed,y = rescale(ci,c(0,80)),colour=inccat,group=inccat),size=1.5) +
geom_point(data = carss1,aes(x = ed,y = rescale(ci,c(0,80))),shape=21,fill="white",size=4)+
scale_y_continuous(breaks=pretty_breaks(4),
sec.axis = sec_axis( ~rescale(.,c(0,5)),name = "ci",labels=sprintf('%.5f',(0:5))))

圖形左軸表示直方圖中購車情況,右軸表示不同收入人群的ci情況,把圖形進一步美化一下
ggplot() +
geom_col( data = carss,aes(x = ed,y = car),fill="#6794a7")+
geom_line(data = carss1,aes(x = ed,y = rescale(ci,c(0,80)),colour=inccat,group=inccat),size=1.5) +
geom_point(data = carss1,aes(x = ed,y = rescale(ci,c(0,80))),shape=21,fill="white",size=4)+
scale_y_continuous(breaks=pretty_breaks(4),
sec.axis = sec_axis( ~rescale(.,c(0,5)),name = "ci",labels=sprintf('%.5f',(0:5))))+
labs(title="This is a Title!",subtitle="This is a Subtitle",caption="This is a Caption")+
theme_minimal(base_size=16) %+replace%
theme(
plot.caption = element_text(hjust=0),
plot.margin = unit(c(1,0.5,1,0.5), "lines")
)

參考文獻
ggplot2雙坐標軸的解決方案 杜雨 https://zhuanlan.zhihu.com/p/31872309
到此這篇關于R語言中ggplot2繪制雙坐標軸圖的文章就介紹到這了,更多相關R語言 ggplot2雙坐標軸圖內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
R語言求一行(列表、list)數(shù)據(jù)的平均數(shù)操作
這篇文章主要介紹了R語言求一行(列表、list)數(shù)據(jù)的平均數(shù)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03

