首頁 > 軟體

R語言中ggplot2繪製雙座標軸圖

2022-08-02 18:09:10

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

今天我們通過我們的汽車銷售資料(公眾號回覆:汽車銷售,可以獲得資料)來演示一下ggplot2繪製雙座標軸圖,主要是通過sec.axis函數進行轉換,進行第二個座標軸的轉換。我們先來匯入資料

library(foreign)
library(ggplot2)
library(plyr)
bc <- read.spss("E:/r/test/tree_car.sav",
                use.value.labels=F, to.data.frame=T)

我們來看下資料,car就是汽車售價,age是年齡,gender是性別,inccat是收入,這裡分成4個等級,ed是教育程度。
我們用這個資料生成兩個子資料,展示不同教育程度人群購車的區別,繼續使用原來的summarySE函數生成資料,想了解這個函數的看《R語言繪製帶誤差和可信區間的折線圖》這篇文章,主要是利用這個函數生成不同型別的資料分析指標,函數的程式碼如下:

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)
}

這個函數並不是今天的主要內容,主要是看我們生成的資料

carss<- summarySE(bc, measurevar="car", groupvars=c("gender","ed"))
carss1<- summarySE(bc, measurevar="car", groupvars=c("inccat","ed"))

我們來看看生成的兩個資料

Carss

carss1

carss1和carss都有ed這個資料,carss1的資料比carss多,carss1有inccat這個指標carss沒有
我們先畫一個carss資料的教育和汽車售價的直方圖

ggplot() +
  geom_col( data = carss,aes(x = ed,y = car),fill="#6794a7")

上圖展示了不同教育程度買車的情況,假設我們想把carss1這個資料的inccat和ci這個指標對映進上圖中(不管臨床意義,只是展示資料對映),我們可以看到ci這個指標很小0-5這樣,而汽車這個指標的範圍是0-80,不能通過同一座標軸展示,所以只能通過分軸展示。主要是通過rescale函數先把ci這個指標在在0-80區間進行標準化轉換,然後在投射於右座標軸。
先把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:資料分析與圖形藝術

ggplot2雙座標軸的解決方案 杜雨 https://zhuanlan.zhihu.com/p/31872309

到此這篇關於R語言中ggplot2繪製雙座標軸圖的文章就介紹到這了,更多相關R語言 ggplot2雙座標軸圖內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com