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


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.