Rにおいて3次元散布図を描く関数scatterplot3d()
について、軸の反転方法を紹介します。
厳密に言うと、軸が反転しているように見せる方法になります。
これにより、scatterplot3d()
でいわゆる「右手系座標」が描画できるようになります。
y軸反転前(手前から奥方向)
y軸反転後(奥から手前)
環境
- OS: Windows10
- R: R x64 4.0.3
- RStudio: Version 1.3.1093
plot()
におけるxlim
を使った軸の反転方法
Rにおいて、plot()
を用いて2次元の散布図を描く場合、xlim
やylim
を用いることで、簡単に軸の向きを反転させることができます。
x軸反転前(デフォルト)
ソースコード
n <- 100
x <- seq(0,2*pi,length=n)
y <- array(1:n)
for(i in 1:n){
y[i] <- sin(x[i])
}
par(mar=c(5,4,4,2))
plot(x,y,
xlim=c(0,7), #x軸反転前(0->7)
pch=c(19,rep(1,n-2),19),
col=c("#FF0000",rep("#000000",n-2),"#00FF00"))
結果
x軸反転後
ソースコード
n <- 100
x <- seq(0,2*pi,length=n)
y <- array(1:n)
for(i in 1:n){
y[i] <- sin(x[i])
}
par(mar=c(5,4,4,2))
plot(x,y,
xlim=c(7,0), #x軸反転後(7->0)
pch=c(19,rep(1,n-2),19),
col=c("#FF0000",rep("#000000",n-2),"#00FF00"))
結果
scatterplot3d()
でもxlim
を使うが…
同じようなことを、3次元の散布図を描くscatterplot3d()
についても行いたいのですが、どうやら仕様により、xlim
等を使っての軸反転はできないようです。
y軸反転前
ソースコード
n <- 100
x <- seq(0,2*pi,length=n)
y <- x
z <- array(1:n)
for(i in 1:n){
z[i] <- sin(x[i])
}
scatterplot3d(x,y,z,
pch=c(19,rep(1,n-2),19),
color=c("#FF0000",rep("#000000",n-2),"#00FF00"),
xlab="x",ylab="y",zlab="z",
ylim=c(0,7), #y軸反転前(0->7)
y.margin.add=0.2
)
結果
y軸反転…を意図
ソースコード
n <- 100
x <- seq(0,2*pi,length=n)
y <- x
z <- array(1:n)
for(i in 1:n){
z[i] <- sin(x[i])
}
scatterplot3d(x,y,z,
pch=c(19,rep(1,n-2),19),
color=c("#FF0000",rep("#000000",n-2),"#00FF00"),
xlab="x",ylab="y",zlab="z",
ylim=c(7,0), #y軸反転を意図(7->0)
y.margin.add=0.2
)
結果(y軸反転せず)
公式ドキュメントにも、xlim
、ylim
、zlim
の項に
Note that setting enlarged limits may not work as exactly as expected (a known but unfixed bug).
とあるので、もしかしたらこれが影響しているのかしれません。
それでもscatterplot3d()
で軸反転させたい!
それでもやっぱり軸反転させたいので、あたかも軸反転しているかのように見せる手段を考えました。
幸い、scatterplot3d()
にはx.ticklabs
等の引数があり、これにより軸の目盛りラベルの値を上書きすることができます。
これを用いて、反転させたい成分に対して、
- プロットデータの対象成分について、値を反転させる
- 対象成分の軸の目盛りラベルの値も反転させる
の2つをすることで、あたかも軸反転しているように見せます。
プロットデータの値を反転させる
仮に、点$x$を点$a$で反転させたいとします。
このとき、反転後の点を$x'$とすると、$x'$は
$x'=-(x-a)+a=2a-x$
により算出されます。
プロットデータの反転させたい成分について、同様のことをすることで、反転することができます。
R上のコードでは、具体的に以下のように書けばOKです。
x <- 2*a - x
ところで、反転の中心となるa
はどのように決めればよいでしょう?
反転したい軸の範囲の中心を設定してあげれば、きれいに軸反転したように見えます。
例えば、y軸について反転させたい場合、y軸の最小値を0
、最大値を7
とすると、
ylim_min <- 0
ylim_max <- 7
ylim_ave <- ave(c(ylim_min,ylim_max))
y <- 2*ylim_ave - y
とすることで、y軸の範囲の中心3.5
で反転させることができます。
軸の目盛りラベルの値を反転させる
先ほど紹介したx.ticklabs
等の引数には、目盛りラベルを小さい方から並べた配列を渡します。
例えば、y軸の目盛りラベルを0
から7
の1
刻みにしたい場合は、scatterplot3d()
の引数に
y.ticklabs=seq(0,7,by=1)
と書けばOKです。
今回は、これを反転させたいので、7
から0
の-1
刻みの配列を渡せばいいので、
y.ticklabs=seq(7,0,by=-1)
となります。
実例
以上をまとめると、以下のソースコードになります。
ソースコード
n <- 100
x <- seq(0,2*pi,length=n)
y <- x
z <- array(1:n)
ylim_min <- 0
ylim_max <- 7
ylim_ave <- ave(c(ylim_min,ylim_max))
for(i in 1:n){
z[i] <- sin(x[i])
}
y <- 2*ylim_ave - y
scatterplot3d(x,y,z,
pch=c(19,rep(1,n-2),19),
color=c("#FF0000",rep("#000000",n-2),"#00FF00"),
xlab="x",ylab="y",zlab="z",
y.ticklabs=seq(7,0,by=-1),
y.margin.add=0.2
)