
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)
根据自己的需要就可以绘制一张完美的二重或三重坐标图了。