有没有办法在R图中对齐2个独立的轴? [英] Is there a way to align 2 independent axes in an R graph?

查看:90
本文介绍了有没有办法在R图中对齐2个独立的轴?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在绘制具有不同轴的图形.问题是我希望2根轴相交一个点,其余的都没有关系.有可能吗?

I'm plotting a graph with different axis. The problem is that I want the 2 axes to be crossing one point, the rest doesn't really matter. Is it possible?

以下是可复制的代码:

plot(x = -10:10, y = -10:10)
abline(v=0,lty = 2)
par(new =TRUE)
plot(x = -10:50, y = seq(-5,5,length.out = length(-10:50)), xaxt = "n", yaxt = "n", bty ="n")
abline(v=0,lty = 3)
axis(3, col="red",col.axis="red",las=2, cex.axis = 1)
axis(4, col="red",col.axis="red",las=2, cex.axis = 1)

以下是输出:

我基本上希望垂直线在0处彼此交叉.

I basically want the vertical lines to be crossing each other at 0.

还有另一种写法吗(这不是很准确,我希望可以自动完成某些事情,而不是手动设置xlim,因为我有很多事情要做.此外,当图像调整大小后,将失去与2 0的对齐):

Is there another way to write this (which is not really accurate, I want something that can be done automatically, other than setting a xlim manually, since I have a lot of them to do. Also, when the image is resized, it's losing the alignment with the 2 0s):

plot(x = -10:10, y = -10:10)
abline(v=0,lty = 2)
par(new =TRUE)
plot(x = -10:50, y = seq(-5,5,length.out = length(-10:50)), 
     xaxt = "n", yaxt = "n", bty ="n",
     xlim = c(-50,50))
abline(v=0,lty = 3, lwd = 5)
axis(3, col="red",col.axis="red",las=2, cex.axis = 1)
axis(4, col="red",col.axis="red",las=2, cex.axis = 1)

输出应使用类似于biplot.prcomp用于对齐箭头和轴的内容:

The output should use something similar to what biplot.prcomp is using to align the arrows and the axis:

已编辑

EDITED

对于PCA,它仅适用于y轴,而不适用于x轴.

With a PCA, it's only working for the y axis, not the x axis.

new_lim <- function(a, type = 1) {
  newdata_ratio <-  NULL
  i <- type * 2 - 1
  old_lim <- par("usr")[i:(i+1)] + c(diff(par("usr")[i:(i+1)]) * 0.04 / 1.08, 
                                     diff(par("usr")[i:(i+1)]) * -0.04 / 1.08)
  old_ratio <- old_lim[1] / old_lim[2]
  newdata_ratio <- if (max(a) <= 0) -1.0e+6 else min(a) / max(a)
  if (old_ratio >= newdata_ratio ) {
    new_min <- min(a)
    new_max <- min(a) / old_ratio
  } else {
    new_min <- max(a) * old_ratio
    new_max <- max(a)
  }
  c(new_min, new_max)
}
s1= rnorm(50,mean = 12)
s2= rnorm(50, mean = 17)
s3= rnorm(50, mean = 20)
library(vegan)
pca=rda(cbind(s1,s2,s3))
pca.scoop=scores(pca, scaling = 2)
biplot(pca)

par(mar=c(4, 4, 4, 4))
plot(pca, xlab = "x1", ylab = "y1",
     type = c("p"),
     main= "main",
     scaling = 2,
     choices = c(1,2),
     xlim =c(min(pca.scoop$sites[,1]),max(pca.scoop$sites[,1])),
     ylim = c(min(pca.scoop$sites[,2]),max(pca.scoop$sites[,2])),
     bty = "o",#"l"
     pch=4)
abline(v = 0, lty = 2); abline(h = 0, lty = 2)

x2 <- -10:20
y2 <- seq(40, 10, length.out = length(x2))
par(new =TRUE)
plot(x2, y2, 
     xlim = new_lim(x2), 
     ylim = new_lim(y2, 2), axes = F, ann = F)
axis(3, col = "red", col.axis = "red") # axes=F is equivalent to xaxt="n", yaxt="n" and bty="n"
axis(4, col = "red", col.axis = "red") # ann=F is equivalent to xlab=NA and ylab=NA
mtext("x2", side = 3, line = 2.5, col = "red")
mtext("y2", side = 4, line = 2.5, col = "red")
# box(bty="7", col="red")  # if you want.

推荐答案

是否可以根据第一个图形对齐第二个图形?

Is it possible to align the second graph based on the first one?

是的.但是,由于需要逻辑判断,所以情况比较复杂.

Yes, it is. But it's a litte complex because of needing logical judgment.

此功能new_lim(a, type)用于计算第一张图的xlim(或ylim)以及图形参数的负号与正号之比.然后,它判断将哪个值用作第二张图的参数(最小(第二个数据)或最大值),并根据第一张图的比率计算另一个值.输出为第二张图的最小值和最大值_lim.参数a是第二个x或y数据. type = 1(默认;可省略)用于xlimtype = 2(type =可省略)用于ylim.

This function, new_lim(a, type), calculates first graph's xlim (or ylim) and ratio of minus to plus from graphic parameters. And it judges which value it uses as second graph's parameter, min(second data) or max, and calculate another value from the first graph's ratio. The output are second graph's min and max value, _lim. The argument a is a second x or y data. type = 1 (default; omittable) is for xlim, type = 2 (type = is omittable) is for ylim.

new_lim <- function(a, type = 1) {
  newdata_ratio <-  NULL
  i <- type * 2 - 1
  old_lim <- par("usr")[i:(i+1)] + c(diff(par("usr")[i:(i+1)]) * 0.04 / 1.08, 
                                     diff(par("usr")[i:(i+1)]) * -0.04 / 1.08)
  old_ratio <- old_lim[1] / old_lim[2]
  newdata_ratio <- if (max(a) <= 0) -1.0e+6 else min(a) / max(a)
  if (old_ratio >= newdata_ratio ) {
    new_min <- min(a)
    new_max <- min(a) / old_ratio
  } else {
    new_min <- max(a) * old_ratio
    new_max <- max(a)
  }
  c(new_min, new_max)
}

[注意] 该函数需要存在于第一个图形中并且包括第一个数据范围的零.第二个数据的范围不包含零是没有问题的.

[Note] This function needs to exist of first graph and include zero of first data's range. It is no problem that second data's range doesn't include zero.

x2 <- -40:20
y2 <- seq(40, 10, length.out = length(-40:20))

par(mar=c(4, 4, 4, 4))
plot(x = -15:5, y = -5:15, xlab = "x1", ylab = "y1")
abline(v = 0, lty = 2); abline(h = 0, lty = 2)

par(new =TRUE)
plot(x2, y2, xlim = new_lim(x2), ylim = new_lim(y2, 2), axes = F, ann = F)
axis(3, col = "red", col.axis = "red") # axes=F is equivalent to xaxt="n", yaxt="n" and bty="n"
axis(4, col = "red", col.axis = "red") # ann=F is equivalent to xlab=NA and ylab=NA
mtext("x2", side = 3, line = 2.5, col = "red")
mtext("y2", side = 4, line = 2.5, col = "red")
# box(bty="7", col="red")  # if you want.

当将此函数与plot(class.rda)一起使用并通过Rsutdio更改纵横比时,输出将变得与您想要的不同.

When you use this function with plot(class.rda) and change the aspect by Rsutdio, the output becomes different from what you want.

x2 <- -10:20
y2 <- seq(40, 10, length.out = length(x2))
library(vegan) 
s1= rnorm(50,mean = 12); s2= rnorm(50, mean = 17); s3= rnorm(50, mean = 20)
pca=rda(cbind(s1,s2,s3))
pca.scoop=scores(pca, scaling = 2)
biplot(pca)
par(new =TRUE)
plot(x2, y2, 
     xlim = new_lim(x2), 
     ylim = new_lim(y2, 2), axes = F, ann = F)
axis(3, col = "red", col.axis = "red")
axis(4, col = "red", col.axis = "red")
mtext("x2", side = 3, line = 2, col = "red")
mtext("y2", side = 4, line = 2, col = "red")

这篇关于有没有办法在R图中对齐2个独立的轴?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆