2014-02-27 3 views
5

6 가지 성격 테스트의 결과를 circumplex로 표시하려고합니다. , JL 네덜란드의 이론에 따라 직업 선택 (Holland codes을 측정 [일반이자 구조 테스트];R에 회전 된 축을 그리는 방법?

문제의 시험은 Allgemeiner Interessen-Struktur 테스트 (Bergmann은 & 에더 2005 AIST-R)이다 RIASEC). 분화의 벡터를 더 잘 시각화하기 위해 관심 프로필 대신 설명서에 권장 된 "Felddarstellung"[현장 표현]을 플로팅하려면 아래 답변을 사용할 수 있습니다.

결과 그래픽이 유사하게 나타납니다

enter image description here

테스트 결과는 각도와 길이로 제공됩니다.

  • 어떻게 (arrows 필요) 최종 좌표를 정의하지 않고, 특정 길이를 기점 R의 축 또는 기하학적 벡터를 그릴 수 있는가?

  • 어떻게 이러한 벡터에 눈금을 추가 할 수 있습니까?

  • 어떻게 좌표 (좌표 대신 원점으로부터 각도와 거리를 제공 하는가?)와 비슷한 방식으로 다각형의 점을 정의 할 수 있습니까?

물론 종단점을 계산할 수 있지만이를 피하고 싶습니다. 또한 화살표에 눈금 표시를 추가하는 방법을 모르겠습니다.

par(pin = c(4, 4)) 
plot(0, 0, type = "n", xlim = c(-60, 60), ylim = c(-60, 60)) 
symbols(c(0, 0, 0), c(0, 0, 0), circles = c(60, 1.5, 1.5), inches = FALSE, add = TRUE, fg = c("black", "black", "white"), bg = c("transparent", "#000000", "transparent")) 
arrows(0, 0, length = c(60, 60, 60, 60, 60, 60), angle = c(0, 60, 120, 180, 240, 300)) 
+2

나는 그들이이라고 생각 ** 레이더 플롯 ** [스타 (참조 스파이더/레이더) 플롯 및 세그먼트 디그 램] (https://stat.ethz.ch/R-manual/R-devel/library/graphics/html/stars.html) – zx8754

+2

[** plotrix **]에서'radial.plot'을보세요 (http://cran.r-project.org/web/packages/plotrix/index.html). – Thomas

+0

적어도 더미 데이터를 제공하고 점과 선으로 플롯을 사용하여 직접 이동해야합니다. – Spacedman

답변

9

다음은 base 기능과 우리가 우리 자신을 정의하는 기능 몇 가지를 사용합니다.

세그먼트의 끝점 좌표를 계산할 필요가없는 방법을 요청했지만 이것이 불가능하다고 생각합니다. 그러나 몇 가지 기본 삼각법을 사용하여 각도 (y 축에서 시계 방향)와 세그먼트 길이를 계산하는 간단한 도우미 함수를 정의 할 수 있습니다. 회전 된 축을 그려주는 함수를 정의 할뿐만 아니라 아래에서이 작업을 수행합니다.

get.coords <- function(a, d, x0, y0) { 
    a <- ifelse(a <= 90, 90 - a, 450 - a) 
    data.frame(x = x0 + d * cos(a/180 * pi), 
      y = y0+ d * sin(a/180 * pi)) 
} 

rotatedAxis <- function(x0, y0, a, d, symmetrical=FALSE, tickdist, ticklen, ...) { 
    if(isTRUE(symmetrical)) { 
    axends <- get.coords(c(a, a + 180), d, x0, y0)  
    tick.d <- c(seq(0, d, tickdist), seq(-tickdist, -d, -tickdist))  
    } else { 
    axends <- rbind(get.coords(a, d, x0, y0), c(x0, y0)) 
    tick.d <- seq(0, d, tickdist) 
    } 
    invisible(lapply(apply(get.coords(a, d=tick.d, x0, y0), 1, function(x) { 
    get.coords(a + 90, c(-ticklen, ticklen), x[1], x[2]) 
    }), function(x) lines(x$x, x$y, ...))) 
    lines(axends$x, axends$y, ...) 
} 

get.coords 인수 a (각도 벡터) d (세그먼트 길이의 벡터) 및 x0y0, 알려진 점의 좌표 걸린다. 벡터 ad은 필요에 따라 재활용됩니다. 이 함수는 각 각도/길이 쌍에 해당하는 좌표를 제공하는 xy 요소가있는 data.frame을 반환합니다.

rotatedAxis은 축이 x0, y0이고 점 d 단위가 각도 a 인 점을 그립니다. symmetricalTRUE 인 경우 축은 반대 방향으로 d 단위까지 확장됩니다. 높이가 ticklen 인 눈금 표시는 tickdist 단위로 표시됩니다.

원을 그리는 것은 원을 따라 좌표를 계산하기 위해 get.coords을 사용하고 이들을 연결하는 선을 polygon (inspired by @timriffe)으로 표시합니다.

이하에서는 OP에서 제공하는 플롯을 복제하기 위해이 기능을 사용합니다.

# Set up plotting device 
plot.new() 
plot.window(xlim=c(-70, 70), ylim=c(-70, 70), asp=1) 

# Plot circle with radius = 60 units and centre at the origin. 
polygon(get.coords(seq(0, 360, length.out=1000), 60, 0, 0), lwd=2) 

# Plot a polygon with vertices along six axes, at distances of 17, 34, 44, 40, 
# 35, and 10 units from the centre. 
poly.pts <- get.coords(seq(0, 300, 60), c(17, 34, 44, 40, 35, 10), 0, 0) 
polygon(poly.pts$x, poly.pts$y, col='gray', lwd=2) 

# Plot the rotated axes 
rotatedAxis(0, 0, a=60, d=60, symmetrical=TRUE, tickdist=10, ticklen=1) 
rotatedAxis(0, 0, a=120, d=60, symmetrical=TRUE, tickdist=10, ticklen=1) 
rotatedAxis(0, 0, a=180, d=60, symmetrical=TRUE, tickdist=10, ticklen=1) 

# Add text labels to circumference 
text.coords <- get.coords(seq(0, 300, 60), 65, 0, 0) 
text(text.coords$x, text.coords$y, c('I', 'A', 'S', 'E', 'C', 'R'))  

# Plot a second point and connect to centre by a line 
point2 <- get.coords(145, 50, 0, 0) 
points(point2, pch=20, cex=2) 
segments(0, 0, point2$x, point2$y, lwd=3) 

# Plot central point 
points(0, 0, pch=21, bg=1, col=0, lwd=2, cex=2) 

(편집 :. 내가 많이이 게시물을 편집 - 변경하지 않고는 크게 일반 메시지입니다 - 순서대로 읽기 쉽고 더 일반적으로 적용하기 위해 추가는/변경은 지금 플롯하는 함수를 정의하는 것이 포함 회전 축, @timriffe 영감으로, 원주를 따라 정점의 좌표를 계산하고 polygon와 플롯으로 원을 그릴.)

enter image description here

+0

아주 좋습니다! 그러나 범위는 실제 값의 10 분의 1입니다. '범위 (틱)'은 -6에서 6까지의 값 범위를 나타냅니다.이 코드를 -60에서 60 범위에 적용하면 어떻게 플롯 릭스 코드와 결합 할 수 있습니까? ? –

+2

틱의 눈금은'ticks.locs <- lapply (seq (60, 360, 60), get.coords, d = 10 * (1 : 6))'로 변경하여 조정할 수 있습니다. 나머지 코드와 호환되도록하려면 몇 가지 조정을해야합니다. 코드를 설명하기 위해 시간이 모자라지만 다시 돌아올 것입니다. 컴퓨터에서 곡선이 물결 모양으로 보이나요? 필자는 항상 Windows의 앤티 앨리어싱에 문제가있었습니다 (다각형에도 물결 모양의 선이 있음). 다른 사람의 시스템에서는 괜찮아 보입니다. – jbaums

+1

FYI : 회전 된 축을 그릴 함수를 정의하여 좀 더 일반적으로 유용하고 유연한 (OP의 정확한 문제와 관련이 없도록)이 게시물을 일부 수정했습니다. 앞서 경험 한 물결 모양 선 문제는 원의 둘레를 따라 정점을 계산하고 '다각형'으로 그려서 완화되었습니다. – jbaums

5

솔루션을 토마스 주석과 jbaums로 답변에 따라 : 작동하지 않았다


내 시도.

  • plotrix에서 제공하는 끊어지지 않은 원형 격자를 원하지 않기 때문에 jbaums 메서드를 사용하여 축을 그렸습니다.
  • 원을 그릴 때 jbaums 메서드를 사용하지 않았습니다. 물결 모양/울퉁불퉁 한 선이 있기 때문입니다.
  • jbaums 응답의 배율이 실제 배율의 1/10이므로 배율을 조정하는 방법을 알 수 없으므로 par(new = TRUE)을 두 번 호출합니다.
  • 필자는 수동으로 lables를 배치했는데 나는 만족스럽지 않습니다.
  • 거기에 많은 불필요한 코드가 있지만 누군가 자신의 버전에서 작동하기 위해 그것을 사용하고 싶을 때를 대비해 놓았습니다.

여기에 코드입니다 :

# test results 
R <- 95 
I <- 93 
A <- 121 
S <- 111 
E <- 114 
C <- 80 

dimensions <- c("R", "I", "A", "S", "E", "C") 
values <- c(R, I, A, S, E, C) 

RIASEC <- data.frame(
       "standard.values" = values, 
       "RIASEC" = dimensions 
      ) 

person.typ <- paste(
        head(
         RIASEC[ 
          with(
           RIASEC, 
           order(-standard.values) 
          ), 
         ]$RIASEC, 
         3 
        ), 
        collapse = "" 
       ) 

# length of vector 
vi1 <- 0 
vi2 <- I 
va1 <- 0.8660254 * A 
va2 <- 0.5 * A 
vs1 <- 0.8660254 * S 
vs2 <- -0.5 * S 
ve1 <- 0 
ve2 <- -E 
vc1 <- -0.8660254 * C 
vc2 <- -0.5 * C 
vr1 <- -0.8660254 * R 
vr2 <- 0.5 * R 
vek1 <- va1 + vi1 + vr1 + vc1 + ve1 + vs1 # x-axix 
vek2 <- vr2 + vi2 + va2 + vs2 + ve2 + vc2 # y-axis 
vektor <- sqrt(vek1^2 + vek2^2)   # vector length 

# angle of vector 
if (vek1 == 0) {tg <- 0} else {tg <- vek2/vek1} 
wink <- atan(tg) * 180/pi 
if (vek1 > 0) { 
    winkel <- 90 - wink 
} else if (vek1 == 0) { 
    if (vek2 >= 0) {winkel <- 360} 
    else if (vek2 < 0) {winkel <- 180} 
} else if (vek1 < 0) { 
    if (vek2 <= 0) {winkel <- 270 - wink} 
    else if (vek2 >= 0) {winkel <- 270 - wink} 
} 

library(plotrix) 
axis.angle <- c(0, 60, 120, 180, 240, 300) 
axis.rad <- axis.angle * pi/180 
value.length <- values - 70 
dev.new(width = 5, height = 5) 
radial.plot(value.length, axis.rad, labels = dimensions, start = pi-pi/6, clockwise=TRUE, 
    rp.type="p", poly.col = "grey", show.grid = TRUE, grid.col = "transparent", radial.lim = c(0,60)) 
radial.plot.labels(value.length + c(4, 2, -2, 1, 1, 4), axis.rad, radial.lim = c(0,60), start = pi-pi/6, clockwise = TRUE, labels = values, pos = c(1,2,3,1,2,1)) 

get.coords <- function(a, d, x0=0, y0=0) { 
    a <- ifelse(a <= 90, 90 - a, 450 - a) 
    data.frame(x = x0 + d * cos(a/180 * pi), y = y0+ d * sin(a/180 * pi) ) 
} 
par(new = TRUE) 
plot(NA, xlim = c(-6, 6), ylim=c(-6, 6), type='n', xlab='', ylab='', asp = 1, 
    axes=FALSE, new = FALSE, bg = "transparent") 
circumf.pts <- get.coords(seq(60, 360, 60), 6) 
segments(circumf.pts$x[1:3], circumf.pts$y[1:3], 
     circumf.pts$x[4:6], circumf.pts$y[4:6]) 
ticks.locs <- lapply(seq(60, 360, 60), get.coords, d=1:6) 

ticks <- c(apply(do.call(rbind, ticks.locs[c(1, 4)]), 1, function(x) 
      get.coords(150, c(-0.1, 0.1), x[1], x[2])), 
      apply(do.call(rbind, ticks.locs[c(2, 5)]), 1, function(x) 
      get.coords(30, c(-0.1, 0.1), x[1], x[2])), 
      apply(do.call(rbind, ticks.locs[c(3, 6)]), 1, function(x) 
      get.coords(90, c(-0.1, 0.1), x[1], x[2]))) 

lapply(ticks, function(x) segments(x$x[1], x$y[1], x$x[2], x$y[2])) 

par(new = TRUE) 
plot(NA, xlim = c(-60, 60), ylim=c(-60, 60), type='n', xlab='', ylab='', asp = 1, 
    axes=FALSE, new = FALSE, bg = "transparent") 
segments(0, 0, vek1, vek2, lwd=3) 
points(vek1, vek2, pch=20, cex=2) 
symbols(c(0, 0, 0), c(0, 0, 0), circles = c(60, 2, 1.3), inches = FALSE, add = TRUE, fg = c("black", "white", "black"), bg = c("transparent", "white", "black")) 

그리고 여기에 그래픽입니다 :

enter image description here

+1

'plotrix' :'library (plotrix);에 흥미로운 그림이 많이 있습니다. 데모 (plotrix, package = "plotrix")' –

+1

당신이 알아 낸 것을 기쁘게 생각합니다. – Thomas

관련 문제