- 要素を円周上に並べ、関連のある要素を円の内側に弧を描くデータ視覚化手法がある。circos
- きれいだけれど、簡易に描きたい
- 特に、データ構造のみの情報で描きたい
- このようなデータ構造は色々考えられるが、自分の用途は次のようなもの
- 木グラフがある。木の周りをぐるりと回ると、それは周回グラフになる。それを円周に配置する
- 木の枝を辿って根から遠い方に進み、先端で折り返して戻ってきて、枝の生え際に帰ってくることになるが、この枝の生え際を複数回通過することを、「同一視」として弧で結ぶことにする。これにより、木の周回というデータ構造を表す用途に使える
- 今、周回グラフがあるとする。それは円周上に等間隔で配置できる
- 周回グラフ上のところどころに、対になるものがあったときに、その間に弧を描きたい
- たとえば (0,4,1,2,10,3,10,1,4,5,6,7,8,4,9) というような要素列で1周とすると、途中に1が2回、10が2回、4が3回登場する。
- 今、単位円周上の2点が、角
で指定されているとき、その2点間に弧を引きたい
- その弧は単位円周と直交するものとすれば、以下のようにその弧は指定できる
とする。
と置く(これは2点の中間方向)
- 弧を含む円の半径は

- 弧を含む円の中心までの距離は

- 弧を含む円の中心の座標は

- 弧は、角
から
まで
- Rで関数にする
my.cirq <- function(x,N=1000){
n <- length(x)
theta <- (0:(n-1))/n * 2*pi
X <- cbind(cos(theta),sin(theta))
d <- as.matrix(dist(x))
diag(d) <- 1
pairs <- which(d==0,arr.ind=TRUE)
pairs <- unique(t(apply(pairs,1,sort)))
alphas <- theta[pairs[,1]]
betas <- theta[pairs[,2]]
rs <- 1/cos((betas-alphas)/2)
ctrs <- rs * cbind(cos((alphas+betas)/2),sin((alphas+betas)/2))
Rs <- tan((betas-alphas)/2)
phis <- cbind(betas+pi/2, alphas+3*pi/2)
Theta <- (0:(N-1))/N * 2 * pi
plot(cos(Theta),sin(Theta),type="l")
points(X,pch=20)
for(i in 1:length(pairs[,1])){
Phi <- seq(from = phis[i,1],to=phis[i,2],length=N)
arc <- Rs[i] * rbind(cos(Phi),sin(Phi)) + ctrs[i,]
points(t(arc),type="l")
}
}
x <- c(0,4,1,2,10,3,10,1,4,5,6,7,8,4,9)
my.cirq(x)
