
x=c(1:10)
y=x
z=10/x
opar=par(no.readonly=TRUE)
par(mar=c(5,4,4,8),0.1)
plot(x,y,type="b",pch=21,col="red",yaxt="n",lty=3,ann=FALSE)
lines(x,z,type="b",pch=22,col="blue",lty=2)
axis(2,at=x,labels=x,col.axis="red",las=2)
axis(4,at=z,labels=round(z,digits=2),col.axis="blue",las=2,cex.lab=0.7,tck=-0.008)
mtext("y=1/x",side=4,line=3,cex.lab=1,las=0,col="blue")
title("An Example of Creative Axes",xlab="X Values",ylab="Y=X")
par(opar)
此時縱軸的量級是一樣的,我的圖片是想要左右量級不同時,也能在一張圖里展示。

思來想去,是不是我沒限定左右兩個坐標軸的范圍呢,試試吧:
x=c(1:10);
y=x;
z=1/x;
opar=par(no.readonly=TRUE)
par(mar=c(5,4,4,8),0.1)
plot(x,y,ylim=c(0,10),type="b",pch=21,col="red",yaxt="n",lty=3,ann=FALSE)
lines(x,z,ylim=c(0,1),type="b",pch=22,col="blue",lty=0,ann=FALSE)## ylim=c(0,1)限定z值的范圍。
axis(2,at=x,labels=x,col.axis="red",las=0)
axis(4,at=c(z[1],'','','','','','','','',z[10]),labels=round(z,digits=2),col.axis="blue",las=2,cex.lab=0.7,tck=-0.008)
##由於z之太密集,為展示好看,令c(z[1],'','','','','','','','',z[10])只顯示兩個值。
mtext("y=1/x",side=4,line=3,cex.lab=1,las=0,col="blue")
title("An Example of Creative Axes",xlab="X Values",ylab="Y=X")
par(opar)
展示圖片如下
但是這個樣子還是不是我想要的。搜羅腦海中關於繪制圖片的R代碼,但是沒想到什么好的辦法來解決。正當絞盡腦汁的時候,看到一個指導。立馬來試一下。
原文介紹是這樣:大家在使用R繪圖的時候,經常使用屬性不同的點或線來展示數據信息,這種數據展示方法貫穿了整個ggplot2系列。使用這種方法時,如果不同指標之間量級相差很大,就會泯滅量級較小指標的的變化,如下圖所示,指標2和指標3幾乎成了一條直線,這幅圖顯然不能充分展示數據信息。
dtf = data.frame(RMB=seq(7000,3400,-200),
指標1=c(200,400,450,500,300,100,400,700,830,1200,400,350,200,700,370,800,200,100,120),
指標2=c(2,5,8,3,2,2,4,7,9,4,4,2,2,7,5,12,5,4,4),
指標3=c(1.2,1.3,1.2,0.9,2.1,1.4,2.9,3.4,2.1,1.1,1.2,1.5,1.2,0.9,0.5,3.3,2.2,1.1,1.2))
library(tidyverse);
library(reshape2)
dtf%>%melt(id='RMB')%>%ggplot(aes(RMB,value,group=variable))+geom_line(aes(linetype=variable))+theme_classic(); 展示如下
今天給大家介紹一種稍微不同的數據展示方法,在同一張圖中使用自由度不同的y軸來展示數據的不同屬性,這種方法可以很好地解決指標量級不同下數據展示問題。
推薦大家使用R基礎繪圖系統繪制這種多重坐標圖,不建議大家使用ggplot2繪圖系統。因為ggplot2的所有工作都是在唯一的坐標系中進行的,如果你分別繪制不同量級的指標,就意味着坐標系統發生變化,必然導致繪圖失敗。但也不能說ggplot2不畫這種圖,只是過程會非常艱辛。Hradly大神也不願看到你那么辛苦地畫了一個十分拙略的圖,他可能會推薦你使用分面的方式展示數據,但分面不是今天的主題。
繪圖策略:首先繪制一張圖片,然后在第一張圖片上繪其他圖片,最后手動添加坐標及圖例。過程非常簡單明了,但其中一些細節大家要注意。在繪制第一張圖時,若繪制雙Y軸要在圖片的右邊留足位置用來添加坐標,若繪制多Y軸坐標要在坐標留出至少10行的距離,右邊盡可能少留空間,若圖像允許可以把右邊留白設為0;第一張圖繪制成功后要調用par(new=T)函數,保證第二張圖是繪制在第一張圖的基礎上,第二張圖繪制成功后,調用aixs繪制坐標刻度,mtext添加坐標標簽。最后使用legend添加圖例,建議大家使用bty='n'去掉圖例的邊框,使用cex=0.85對字體進行放縮。
另外如果只想繪制雙Y坐標軸,可以使用plotrix包中的twoord.plot和twoord.stackplot,兩者稍有區別,前者使用不同Y軸相同的X軸,后者在同一張圖上使用不同的坐標系。還有lattice包中的doubleYScale函數,Plotly直接在add_lines函數中聲明要繪制雙Y軸即可,highcharter中通過hc_add_series直接添加不同尺度的Y軸。
這才是想要的樣子么。這樣的圖是怎么繪制呢?別急,代碼來了,
雙重坐標軸:
op=par(mar = c(5,5,2,5),cex.axis=0.6,cex.lab=0.75)
with(dtf, plot(RMB, 指標1, type="l", col="gray10", ylab='指標1',ylim=c(0,1300)))
par(new = T)
with(dtf, plot(RMB, 指標2, type="l", axes=F, xlab=NA, ylab=NA,lty=2,col="gray30"))
axis(side = 4)
mtext(side = 4, line = 3, '指標2',cex=0.75)
legend("topright",cex = 0.75,legend=c('指標1', '指標2'),bty = 'n',lty=c(1,2), col=c("gray10", "gray30"))
title(main = 'base:雙重坐標軸',cex=0.8,font=1)
par(op)
三重坐標軸:
attach(dtf)
op=par(mar=c(4, 11, 2, 1) + 0.1,cex.axis=0.75)
plot(RMB, 指標1, axes=F, ylim=c(0,max(指標1)), xlab='', ylab='',type='l',col='black', main='',xlim=c(7000,3400))
axis(2, ylim=c(0,max(指標1)),col='black',lwd=2)
mtext(2,text='指標1',line=2,cex = 0.75)
par(new=T)
plot(RMB, 指標2, axes=F, ylim=c(0,max(指標2)), xlab='', lty=2,ylab='',type='l',col='black', main='',xlim=c(7000,3400))
axis(2, ylim=c(0,max(指標2)),col='black',lwd=2,line=3.5)
mtext(2,text='指標2',line=5.5,cex = 0.75)
par(new=T)
plot(RMB, 指標3, axes=F, ylim=c(0,max(指標3)), xlab='', lty=3,ylab='',type='l',col='black', main='',xlim=c(7000,3400))
axis(2, ylim=c(0,max(指標2)),col='black',lwd=2,line=7)
mtext(2,text='指標3',line=9,cex = 0.75)
axis(1,pretty(range(RMB),10))
mtext('RMB',side=1,col='black',line=2,cex=0.75)
legend('topleft',cex=0.65,bty='n',legend=c('指標1','指標2','指標3'),lty=c(1,2,3))
title(main = 'base:三重坐標軸',cex=0.8,font=1)
par(op)
根據自己的需要就可以繪制一張完美的二重或三重坐標圖了。