Temel grafiklerde çizim alanının dışında bir açıklama çizilsin mi?


185

Başlığın dediği gibi: Temel grafikleri kullanırken bir efsaneyi çizim alanının dışında nasıl çizebilirim?

Etrafta dolaşmayı layoutve sadece efsaneyi içermek için boş bir arsa üretmeyi düşündüm , ancak sadece temel grafik tesislerini kullanarak ve örneğin, par(mar = )efsane için arsanın sağında biraz yer almakla ilgilenirim .


İşte bir örnek:

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))

üretir:

alternatif metin

Ama dediğim gibi, efsanenin çizim alanının dışında olmasını istiyorum (örneğin, grafiğin / grafiğin sağında).


... ayrıca efsane, kolay ve oldukça rahat zaman zaman için kukla konteyner ile eşit kesmek. Benzer soru burada .
hhh

3
@hhh Bağlantı artık çalışmıyor. Bu yaklaşımı kullanarak güncelleyebilir veya yanıt gönderebilir misiniz?
Henrik

Yanıtlar:


111

Belki ihtiyacınız olan par(xpd=TRUE)şey olayların arsa bölgesinin dışına çekilmesini sağlamaktır. Yani ana arsa ile bty='L'yaparsanız, bir efsane için sağda biraz alanınız olacak. Normalde bu arsa bölgesine kırpılır, ancak yapın par(xpd=TRUE)ve biraz ayar yaparak mümkün olduğunca doğru bir efsane alabilirsiniz:

 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
Daha sonra par sıfırlama konusunda endişelenmenize gerek kalmaması için xpd'yi doğrudan göstergeye aktarabileceğinizi unutmayın. Ayrıca, göstergenin konumunu, çizdiğiniz verilerin sınırlarına bağlı olmayacak şekilde belirtmenin bir yolu için grconvertX & Y'ye bakın.
Charles

6
Bu soru ve cevap hala çok popüler olduğu için, par(xpd=NA)daha da güçlüdür (yani, daha fazla bölgeye çizim).
Henrik

+1. parEfsaneden hemen önce ayrı bir çağrı yapmanın mantıklı olduğunu belirtmeliyiz . Benim planımda, par(new=T)başka birçok kez kullandım ve sadece xpdaynı çağrıda param eklemek istedim , bu da soruna neden oluyor.
Matt Bannert

146

Hiç kimse için negatif insetdeğerler kullanarak bahsetmedi legend. Göstergenin çizimin sağında, üste hizalanmış olduğu bir örnek (anahtar kelime kullanarak "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")

İlk değerinin inset=c(-0.2,0)efsanenin genişliğine göre ayarlanması gerekebilir.

legend_right


14
@Henrik hayır xpd = TRUE olmadan çalışmaz. Ayrıca xpd = TRUE değerini legend () işlevinin bir argümanı olarak ayarlamanın daha iyi olduğunu unutmayın.
Stéphane Laurent

1
Negatif iç kısmın çalışması için bazen xpdolarak ayarlanmalıdır TRUE. Ama bazen değil. args.legend=list(x="bottom", horiz=TRUE, inset=-0.2)İçindeki komutla barplot(...ihtiyaç duyulmamış gibi görünüyor, xpd=TRUEancak legend(x="bottom", horiz=TRUE, inset=-0.2)ihtiyaç duyduğu gibi görünüyor xpd=TRUE. Herhangi bir görüşün var mı? Argümanlarımı iletmekte kafam karıştı mı?
user3386170

28

Başka bir çözüm, daha önce bahsedilen ( layoutveyapar(xpd=TRUE) ) işaretlerin tüm cihazın üzerine arsa üzerinde şeffaf bir arsa yerleştirmek ve daha sonra efsaneyi buna eklemektir.

İşin püf noktası, (boş) bir grafiği tüm çizim alanı üzerine yerleştirmek ve göstergeyi buna eklemek. par(fig=...)Seçeneği kullanabiliriz . İlk olarak R'ye tüm çizim cihazı üzerinde yeni bir çizim oluşturmasını söyleriz:

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

Ayarın omave mararsanın iç kısmının tüm cihazı kaplamasını istediğimiz için gereklidir. new=TRUER'nin yeni bir cihaz başlatmasını önlemek için gereklidir. Daha sonra boş grafiği ekleyebiliriz:

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

Ve efsaneyi eklemeye hazırız:

legend("bottomright", ...)

cihazın sağ alt kısmına bir açıklama ekleyecektir. Benzer şekilde, efsaneyi üst veya sağ kenar boşluğuna ekleyebiliriz. Sağlamamız gereken tek şey, orijinal arsanın marjının efsaneyi karşılayacak kadar büyük olmasıdır.

Tüm bunları bir işleve koymak;

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(...)
}

Ve bir örnek. Öncelikle, efsaneyi eklemek için altta yeterli alanımız olduğundan emin olun.

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

Sonra efsaneyi ekleyin

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

Sonuçlanan:

Göstergeyi üst kenar boşluğunda gösteren örnek şekil


2
Bu listeye harika bir ek. Buradaki grafikte birden fazla parsel ile bu çalışmanın nasıl yapılacağı hakkında bir açıklama var .
shiri

Jan, bir metin kırpılmadan, yazı tipinin yazı tipi boyutunu artırmanın bir yolu var mı? Örneğin, 4 farklı türde bir grafik var, ancak aralarında çok fazla boşluk var.
Denizde yaşlı bir adam.

Daha fazla ayrıntı içeren bir soru yazdım stackoverflow.com/questions/42707308/…
Denizdeki yaşlı bir adam.

16

Eski bir diziyi dirilttiğim için özür dilerim, ama bugün de aynı sorunla karşılaştım. Bulduğum en basit yol şudur:

# 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)

Burada bulundu: http://www.harding.edu/fmccown/R/


4
Daha da iyisi oldpar <- par (xpd = T, mar = par () $ mar + c (0,0,0,6)) ... par (oldpar) (par yardımına bakın)
rakensi

Bu çözüm daha iyidir çünkü efsane alanı, efsane dizelerinin uzunluğu ne olursa olsun sabittir
Sergio

15

Ben böyle yapmak istiyorum:

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))

resim açıklamasını buraya girin

Gereken tek değişiklik, doğru kenar boşluğunun efsaneyi karşılayacak kadar geniş olmasını sağlamaktır.

Ancak, bu otomatikleştirilebilir:

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))

resim açıklamasını buraya girin


Xpd = T veya xpd = NA kullanmak, geniş ana kenar boşluğuyla eklenen alanı kullanmaya çalışmak için uzatıldığında 'ana' (başlık) öğemin kırpılmasını engellemez.
Phil Goetz

@PhilGoetz arsa alanı içinde ana plan yaptığınızdan emin misiniz? Orada çizim yapmak için yeterli marj satırınız olmayabilir mi?
jbaums

10

Son zamanlarda istediğiniz yere çizim alanı dışında efsane yazdırmak için çok kolay ve ilginç bir işlev buldum.

Dış kenar boşluğunu grafiğin sağ tarafında yapın.

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

Bir komplo oluştur

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")

Açıklama ekleyin ve aşağıdaki gibi konumlandırıcı (1) işlevini kullanın. Sonra aşağıdaki komut dosyasını yükledikten sonra istediğiniz yere tıklamanız yeterlidir.

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

Dene


9

Daha önce belirtilen yerleşim çözümünün sadece bir örneğini sunabilirim.

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))

çirkin bir resim: S


9

Bence oldukça zarif başka bir basit alternatif eklemek.

Arsa:

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")

Açıklama:

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"
       )

Sonuç:

efsane ile resim

Burada örneğinize efsanenin sadece ikinci satırı eklendi. Sırayla:

  • inset=c(0,1)- göstergeyi (x, y) yönünde çizim bölgesinin kesiriyle hareket ettirir. Bu durumda efsane "bottomright"pozisyondadır. X yönünde 0 çizim bölgesi (bu nedenle "sağda kalır") ve y yönünde 1 çizim bölgesi (aşağıdan yukarıya) hareket ettirilir. Ve böylece grafiğin hemen üstünde görünür.
  • xpd=TRUE - efsane çizim bölgesinin dışında görünelim.
  • horiz=TRUE - yatay bir gösterge oluşturma talimatı verir.
  • bty="n" - efsane sınırlayıcı kutudan kurtulmak için bir stil detayı.

Yan tarafa efsane eklerken aynı şey geçerlidir:

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"
       )

Burada sadece gösterge konumlarını ayarladık ve arsanın sağ tarafına ek kenar boşluğu ekledik. Sonuç:

efsane 2 ile resim


4

Bunu Plotly R API'sı ile yapabilirsiniz ile ya kodla ya da göstergeyi istediğiniz yere sürükleyerek .

İşte bir örnek. Grafik ve kod da burada .

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)

100 veya -100'e x ve y değerlerinden birini atayarak göstergeyi grafiğin dışına yerleştirebilirsiniz.

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

Diğer seçenekler şunlardır:

  • list("x" = 100, "y" = 0) Sağ Alt Dış için
  • list("x" = 100, "y"= 1) Dış Sağ Üst
  • list("x" = 100, "y" = .5) Dış Orta Sağ
  • list("x" = 0, "y" = -100) Sol Altında
  • list("x" = 0.5, "y" = -100) Merkez Altında
  • list("x" = 1, "y" = -100) Sağ Altında

Sonra cevap.

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

Arama yaptığınızda grafiğinizle birlikte bir URL döndürür. browseURL(response$url)Grafiğinizi sizin için tarayıcınızda açması için arayarak buna daha hızlı erişebilirsiniz .

url = response$url
filename = response$filename

Bu bize bu grafiği verir. Göstergeyi GUI içinden de taşıyabilirsiniz, ardından grafik buna göre ölçeklenir. Tam açıklama: Plotly ekibindeyim.

Grafiğin yan tarafındaki açıklama


2

Deneyin layout()Geçmişte bunun için kullandığım, aşağıdaki boş bir arsa oluşturarak, yaklaşık 1/4 civarında düzgün bir şekilde ölçeklendirilmiş ve efsane parçalarını manuel olarak yerleştirerek .

Burada legend()başlamanız gereken bazı eski sorular var .


Soruda daha önce de söylediğim gibi, ben de bunu düşündüm. Ama başka bir yol olsaydı ideal olurdu. Bir şekilde sanmıyorum.
Henrik
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.