기본 그래픽에서 플로팅 영역 외부에 범례를 플롯 하시겠습니까?


185

제목에서 알 수 있듯이 : 기본 그래픽을 사용할 때 플로팅 영역 외부에 범례를 플로팅하려면 어떻게해야합니까?

나는 layout범례 만 포함하고 빈 플롯을 만들어내는 것에 대해 생각 했지만 기본 그래프 기능 만 사용하는 방법에 관심이있을 것 par(mar = )입니다.


예를 들면 다음과 같습니다.

plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")
legend(1,-1,c("group A", "group B"), pch = c(1,2), lty = c(1,2))

생산 :

대체 텍스트

그러나 말했듯이 범례가 플로팅 영역 밖에 있어야합니다 (예 : 그래프 / 플롯의 오른쪽).


... 당신은 또한 전설적이고 쉽고 편리한 시간을 위해 더미 컨테이너로 파를 해킹 할 수 있습니다. 비슷한 질문이 있습니다 .
— hhh

3
@hhh 링크가 더 이상 작동하지 않습니다. 이 방법을 사용하여 업데이트하거나 답변을 게시 할 수 있습니까?
— Henrik

답변:


111

아마도 필요한 것은 par(xpd=TRUE)플롯 영역 외부에 물건을 그릴 수있게하는 것입니다. 메인 플롯을 사용 bty='L'하면 오른쪽에 범례를위한 공간이 생깁니다. 일반적으로 이것은 플롯 영역에 잘리지 만 par(xpd=TRUE)약간의 조정만으로도 가능한 한 범례를 얻을 수 있습니다.

 set.seed(1) # just to get the same random numbers
 par(xpd=FALSE) # this is usually the default

 plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2), bty='L')
 # this legend gets clipped:
 legend(2.8,0,c("group A", "group B"), pch = c(1,2), lty = c(1,2))

 # so turn off clipping:
 par(xpd=TRUE)
 legend(2.8,-1,c("group A", "group B"), pch = c(1,2), lty = c(1,2))

33
xpd를 범례에 직접 전달할 수 있으므로 나중에 par를 재설정 할 필요가 없습니다. 또한 플로팅하는 데이터의 한계에 의존하지 않는 방식으로 범례의 위치를 ​​지정하는 방법에 대해서는 grconvertX & Y를 참조하십시오.
— 찰스

6
이 질문과 답변은 여전히 ​​매우 인기 par(xpd=NA)가 있기 때문에 훨씬 강력합니다 (즉, 더 많은 지역에 플롯).
— Henrik

+1. 우리는 par전설 직전에 별도의 전화 를하는 것이 합리적이라고 언급해야합니다 . 내 음모에서 par(new=T)다른 여러 경우 xpd에 사용했으며 동일한 호출에서 매개 변수 를 추가하기 만하면 문제가 발생했습니다.
— Matt Bannert

146

에 inset대해 음수 값을 사용한다고 언급 한 사람은 없습니다 legend. 다음은 범례가 플롯의 오른쪽에 있고 키워드를 사용하여 상단에 정렬 된 예 "topright"입니다.

# Random data to plot:
A <- data.frame(x=rnorm(100, 20, 2), y=rnorm(100, 20, 2))
B <- data.frame(x=rnorm(100, 21, 1), y=rnorm(100, 21, 1))

# Add extra space to right of plot area; change clipping to figure
par(mar=c(5.1, 4.1, 4.1, 8.1), xpd=TRUE)

# Plot both groups
plot(y ~ x, A, ylim=range(c(A$y, B$y)), xlim=range(c(A$x, B$x)), pch=1,
               main="Scatter plot of two groups")
points(y ~ x, B, pch=3)

# Add legend to top right, outside plot region
legend("topright", inset=c(-0.2,0), legend=c("A","B"), pch=c(1,3), title="Group")

inset=c(-0.2,0)범례의 너비에 따라 첫 번째 값을 조정해야 할 수도 있습니다.

legend_right


14
@Henrik 아니오 xpd = TRUE 없이는 작동하지 않습니다. 또한 xpd = TRUE를 legend () 함수의 인수로 설정하는 것이 좋습니다.
— Stéphane Laurent

1
때로는 음의 삽입이 작동 xpd하도록 설정해야합니다 TRUE. 그러나 때로는 그렇지 않습니다. 명령과 함께 args.legend=list(x="bottom", horiz=TRUE, inset=-0.2)내에서 barplot(...그것은 필요에 seemd하지 않습니다 xpd=TRUE하지만 단지로 legend(x="bottom", horiz=TRUE, inset=-0.2)그것을 필요로 보인다 xpd=TRUE. 통찰력이 있습니까? 나는 논쟁을 전달하는 데 혼란스러워?
— user3386170

28

이미 언급 한 ( layout또는 사용 par(xpd=TRUE)) 외에 다른 해결책 은 전체 장치에 대해 플롯을 투명 플롯으로 오버레이 한 다음 범례를 추가하는 것입니다.

트릭은 전체 플로팅 영역에 (빈) 그래프를 오버레이하고 범례를 추가하는 것입니다. par(fig=...)옵션을 사용할 수 있습니다 . 먼저 전체 플로팅 장치에 대해 새로운 플롯을 만들도록 R에 지시합니다.

par(fig=c(0, 1, 0, 1), oma=c(0, 0, 0, 0), mar=c(0, 0, 0, 0), new=TRUE)

플롯의 내부가 전체 장치를 커버하도록 설정 oma하고 mar필요합니다. new=TRUER이 새로운 장치를 시작하지 못하도록해야합니다. 그런 다음 빈 줄거리를 추가 할 수 있습니다.

plot(0, 0, type='n', bty='n', xaxt='n', yaxt='n')

그리고 범례를 추가 할 준비가되었습니다 :

legend("bottomright", ...)

기기의 오른쪽 하단에 범례를 추가합니다. 마찬가지로 범례를 상단 또는 오른쪽 여백에 추가 할 수 있습니다. 우리가 보장해야 할 유일한 것은 원래 줄거리의 마진이 범례를 수용하기에 충분히 크다는 것입니다.

이 모든 것을 함수에 넣는 것;

add_legend <- function(...) {
  opar <- par(fig=c(0, 1, 0, 1), oma=c(0, 0, 0, 0), 
    mar=c(0, 0, 0, 0), new=TRUE)
  on.exit(par(opar))
  plot(0, 0, type='n', bty='n', xaxt='n', yaxt='n')
  legend(...)
}

그리고 예입니다. 먼저 하단에 범례를 추가하기에 충분한 공간이 있는지 확인하는 플롯을 만듭니다.

par(mar = c(5, 4, 1.4, 0.2))
plot(rnorm(50), rnorm(50), col=c("steelblue", "indianred"), pch=20)

그런 다음 범례를 추가하십시오

add_legend("topright", legend=c("Foo", "Bar"), pch=20, 
   col=c("steelblue", "indianred"),
   horiz=TRUE, bty='n', cex=0.8)

를 야기하는:

상단 여백에 범례가 표시된 예제 그림


2
여기에 목록에 추가되었습니다. 여기 그래픽의 여러 플롯 으로이 작업을 수행하는 방법에 대한 설명이 있습니다 .
— shiri

Jan, 일부 텍스트가 잘리지 않고 범례의 글꼴 크기를 늘리는 방법이 있습니까? 예를 들어 그래픽에는 4 가지 유형의 레이블이 있지만 레이블 사이에 빈 공간이 많이 있습니다.
— 바다에있는 노인.

자세한 내용을 질문으로 작성했습니다 stackoverflow.com/questions/42707308/…
— 바다의 노인.

16

오래된 스레드를 부활 시켜서 죄송하지만 오늘 같은 문제가있었습니다. 내가 찾은 가장 간단한 방법은 다음과 같습니다.

# Expand right side of clipping rect to make room for the legend
par(xpd=T, mar=par()$mar+c(0,0,0,6))

# Plot graph normally
plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")

# Plot legend where you want
legend(3.2,1,c("group A", "group B"), pch = c(1,2), lty = c(1,2))

# Restore default clipping rect
par(mar=c(5, 4, 4, 2) + 0.1)

여기에서 찾을 수 있습니다 : http://www.harding.edu/fmccown/R/


4
oldpar <-par (xpd = T, mar = par () $ mar + c (0,0,0,6)) ... par (oldpar) (par의 도움말 참조)
— rakensi

이 솔루션은 범례의 길이가 범례의 길이와 상관없이 고정되기 때문에 더 좋습니다
— Sergio

15

나는 다음과 같이하고 싶다 :

par(oma=c(0, 0, 0, 5))
plot(1:3, rnorm(3), pch=1, lty=1, type="o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch=2, lty=2, type="o")
legend(par('usr')[2], par('usr')[4], bty='n', xpd=NA,
       c("group A", "group B"), pch=c(1, 2), lty=c(1,2))

여기에 이미지 설명을 입력하십시오

범례를 수용 할 수 있도록 오른쪽 여백을 넓게 설정해야합니다.

그러나 이것은 또한 자동화 될 수 있습니다 :

dev.off() # to reset the graphics pars to defaults
par(mar=c(par('mar')[1:3], 0)) # optional, removes extraneous right inner margin space
plot.new()
l <- legend(0, 0, bty='n', c("group A", "group B"), 
            plot=FALSE, pch=c(1, 2), lty=c(1, 2))
# calculate right margin width in ndc
w <- grconvertX(l$rect$w, to='ndc') - grconvertX(0, to='ndc')
par(omd=c(0, 1-w, 0, 1))
plot(1:3, rnorm(3), pch=1, lty=1, type="o", ylim=c(-2, 2))
lines(1:3, rnorm(3), pch=2, lty=2, type="o")
legend(par('usr')[2], par('usr')[4], bty='n', xpd=NA,
       c("group A", "group B"), pch=c(1, 2), lty=c(1, 2))

여기에 이미지 설명을 입력하십시오


xpd = T 또는 xpd = NA를 사용한다고해서 오른쪽 여백이 추가 된 영역을 사용하도록 늘릴 때 '메인'(제목)이 잘리는 것을 막을 수 없습니다.
— Phil Goetz

@ 필 고츠 (PhilGoetz) 당신은 당신이 줄거리 영역 내에서 메인을 플로팅하고 있습니까? 플롯 할 여백이 충분하지 않을 수 있습니까?
— jbaums

10

최근에 원하는 플롯 영역 외부에서 범례를 인쇄하는 매우 쉽고 재미있는 기능을 발견했습니다.

플롯의 오른쪽에 외부 여백을 만듭니다.

par(xpd=T, mar=par()$mar+c(0,0,0,5))

줄거리 만들기

plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")

범례를 추가하고 아래와 같이 locator (1) 함수를 사용하십시오. 그런 다음 스크립트를로드 한 후 원하는 위치를 클릭하면됩니다.

legend(locator(1),c("group A", "group B"), pch = c(1,2), lty = c(1,2))

시도 해봐


9

이미 지적한 레이아웃 솔루션의 예만 제공 할 수 있습니다.

layout(matrix(c(1,2), nrow = 1), widths = c(0.7, 0.3))
par(mar = c(5, 4, 4, 2) + 0.1)
plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")
par(mar = c(5, 0, 4, 2) + 0.1)
plot(1:3, rnorm(3), pch = 1, lty = 1, ylim=c(-2,2), type = "n", axes = FALSE, ann = FALSE)
legend(1, 1, c("group A", "group B"), pch = c(1,2), lty = c(1,2))

못생긴 사진 : S


9

내 의견으로는 매우 우아한 또 다른 간단한 대안을 추가합니다.

당신의 음모 :

plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")

전설:

legend("bottomright", c("group A", "group B"), pch=c(1,2), lty=c(1,2),
       inset=c(0,1), xpd=TRUE, horiz=TRUE, bty="n"
       )

결과:

전설 사진

여기에 범례의 두 번째 줄만 예제에 추가되었습니다. 차례로:

  • inset=c(0,1)-(x, y) 방향으로 플롯 영역의 비율로 범례를 이동합니다. 이 경우 범례가 제 "bottomright"위치에 있습니다. x 방향으로 0 개의 플로팅 영역 ( "오른쪽"에 유지됨)과 y 방향으로 1 개의 플로팅 영역 (하단에서 상단)으로 이동합니다. 그리고 그것은 플롯 바로 위에 나타납니다.
  • xpd=TRUE -범례가 플로팅 영역 외부에 나타납니다.
  • horiz=TRUE -가로 범례를 생성하도록 지시합니다.
  • bty="n" -범례 경계 상자를 제거하는 스타일 세부 사항.

측면에 범례를 추가 할 때도 마찬가지입니다.

par(mar=c(5,4,2,6))
plot(1:3, rnorm(3), pch = 1, lty = 1, type = "o", ylim=c(-2,2))
lines(1:3, rnorm(3), pch = 2, lty = 2, type="o")

legend("topleft", c("group A", "group B"), pch=c(1,2), lty=c(1,2),
       inset=c(1,0), xpd=TRUE, bty="n"
       )

여기서 범례 위치를 간단히 조정하고 플롯 오른쪽에 여백 공간을 추가했습니다. 결과:

전설 2와 그림


4

당신은이 작업을 수행 할 수 Plotly R의 API 중 코드, 또는 GUI에서 당신이 그것을 원하는 전설을 끌어.

다음은 예입니다. 그래프와 코드도 여기에 있습니다 .

x = c(0,1,2,3,4,5,6,7,8) 
y = c(0,3,6,4,5,2,3,5,4) 
x2 = c(0,1,2,3,4,5,6,7,8) 
y2 = c(0,4,7,8,3,6,3,3,4)

x 및 y 값 중 하나를 100 또는 -100에 지정하여 범례를 그래프 외부에 배치 할 수 있습니다.

legendstyle = list("x"=100, "y"=1)
layoutstyle = list(legend=legendstyle)

다른 옵션은 다음과 같습니다.

  • list("x" = 100, "y" = 0) 외부 오른쪽 하단
  • list("x" = 100, "y"= 1) 외부 오른쪽 상단
  • list("x" = 100, "y" = .5) 외부 오른쪽 중간
  • list("x" = 0, "y" = -100) 왼쪽 아래
  • list("x" = 0.5, "y" = -100) 센터에서
  • list("x" = 1, "y" = -100) 오른쪽 아래

그런 다음 응답.

response = p$plotly(x,y,x2,y2, kwargs=list(layout=layoutstyle));

전화를 걸 때 그래프와 함께 URL을 플롯합니다. 호출하면 더 빠르게 액세스 할 수 browseURL(response$url)있으므로 브라우저에서 그래프가 열립니다.

url = response$url
filename = response$filename

그것은 우리에게이 그래프를 제공합니다. GUI 내에서 범례를 이동하면 그에 따라 그래프의 크기가 조정됩니다. 전체 공개 : 저는 Plotly 팀에 있습니다.

그래프 측면의 범례


2

layout()과거에 빈 플롯을 만들고 약 1/4 정도의 크기로 적절하게 조정하고 범례 부분을 수동으로 배치하여 과거에 내가 사용한 것을 사용해보십시오 .

여기서 legend()시작해야 할 몇 가지 오래된 질문이 있습니다 .


질문에서 이미 언급했듯이 이것도 내가 생각한 것입니다. 그러나 다른 방법이 있다면 이상적입니다. 어쨌든 나는 없다고 생각합니다.
— Henrik
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.