ggplot2'deki geom_point npc koordinatları


10

Referans çerçevesinin tüm çizilen görüntünün olduğu bir ggplot'ta geom_point'in x , y koordinatlarını nasıl alabilirim ?

Bazı geom_point s kullanarak bir ggplot oluşturabilirsiniz :

library(ggplot2)

my.plot <- ggplot(data.frame(x = c(0, 0.456, 1), y = c(0, 0.123, 1))) +
             geom_point(aes(x, y), color = "red")

Bu şunu verir:

resim açıklamasını buraya girin

Bunu bir oyuğa dönüştürerek , bu ggplot hakkında , mor okla işaretlenmiş arsa paneline ilişkin koordinatlar gibi bazı ek bilgiler çıkarabilirim . Ancak bu, eksenlerin kapladığı alanı görmezden gelir.

my.grob <- ggplotGrob(my.plot)
my.grob$grobs[[6]]$children[[3]]$x
# [1] 0.0454545454545455native 0.46native 0.954545454545454native 
my.grob$grobs[[6]]$children[[3]]$y
# [1] 0.0454545454545455native 0.157272727272727native 0.954545454545454native

Yeşil okla işaretlenmiş tüm görüntünün sol alt köşesinden ölçmeye başladığımda x , y koordinatlarının değerlerini nasıl alabilirim ?

Mümkünse, ben dikkate almak çözüm istiyoruz tema ait ggplot . Benzeri bir tema eklemek + theme_void()eksenleri etkiler ve ayrıca çizilen görüntünün tamamına göre noktaların konumunu kaydırır.

Güncelleme : Eksenlerin yazı tipi boyutunun, çizimin genişliğine ve yüksekliğine bağlı olarak, çizim panelinin göreceli boyutunu etkileyeceğini fark ettim . Bu nedenle , çizim genişliğini ve çizim yüksekliğini tanımlamadan konumu npc birimlerinde sağlamak önemsiz olmayacaktır . Mümkünse, çizim genişliğinin ve çizim yüksekliğinin bir fonksiyonu olarak geom_ noktalarının konumunu belirtin .


5
Neden 2 downvotes?
markus

2
Evet, endişeleriniz veya önerileriniz varsa lütfen yorum yapın.
LBogaardt

1
Çizimin kendisinin sabit boyutları olmadığını düşünün - mutlak nokta konumları yalnızca yazdırdığınız aygıtın boyutuna değil, aynı zamanda eksenlerinizin oranına da bağlıdır. Bu nedenle neye ihtiyacınız olduğunu merak ediyorum
Tjebo

1
Aşağı oylarla ilgili olarak, SE hakkında geçerli bir soru olması için sorumu haklı çıkarmam gerekmediğini unutmayın. Neden bilmek istiyorum? Çünkü ben yapıyorum.
LBogaardt

1
bu da. ama asla gerçek bir cevap
alamadım

Yanıtlar:


5

Bir ggplot'u yeniden boyutlandırdığınızda, panel içindeki öğelerin konumu npc alanında sabit konumlarda değildir. Bunun nedeni, arsanın bazı bileşenlerinin sabit boyutlara sahip olması ve bazılarının (örneğin panel) aygıtın boyutuna göre boyutları değiştirmesidir.

Bu, herhangi bir çözümün cihaz boyutunu dikkate alması gerektiği anlamına gelir ve çizimi yeniden boyutlandırmak isterseniz, hesaplamayı yeniden çalıştırmanız gerekir. Çoğu uygulama için (sizinki dahil, bir şeylerin sesleri ile), bunun bir sorun olmadığını söyledikten sonra.

Başka bir zorluk, panel grob içindeki doğru grobları tanımladığınızdan emin olmaktır ve bunun nasıl kolayca genelleştirilebileceğini görmek zordur. Liste alt kümesi fonksiyonlarını kullanma [[6]]ve [[3]]sizin örnekte diğer parsellere genellenebilir değildir.

Her neyse, bu çözüm, panel boyutundaki panel boyutunu ve konumunu ölçerek ve npc alanına dönüştürmek için milimetre cinsinden çizim boyutlarına bölmeden önce tüm boyutları milimetreye dönüştürerek çalışır. Sayısal indeks yerine panel ve noktaları isme göre biraz daha genel hale getirmeye çalıştım.

library(ggplot2)
library(grid)
require(gtable)

get_x_y_values <- function(gg_plot)
{
  img_dim      <- grDevices::dev.size("cm") * 10
  gt           <- ggplot2::ggplotGrob(gg_plot)
  to_mm        <- function(x) grid::convertUnit(x, "mm", valueOnly = TRUE)
  n_panel      <- which(gt$layout$name == "panel")
  panel_pos    <- gt$layout[n_panel, ]
  panel_kids   <- gtable::gtable_filter(gt, "panel")$grobs[[1]]$children
  point_grobs  <- panel_kids[[grep("point", names(panel_kids))]]
  from_top     <- sum(to_mm(gt$heights[seq(panel_pos$t - 1)]))
  from_left    <- sum(to_mm(gt$widths[seq(panel_pos$l - 1)]))
  from_right   <- sum(to_mm(gt$widths[-seq(panel_pos$l)]))
  from_bottom  <- sum(to_mm(gt$heights[-seq(panel_pos$t)]))
  panel_height <- img_dim[2] - from_top - from_bottom
  panel_width  <- img_dim[1] - from_left - from_right
  xvals        <- as.numeric(point_grobs$x)
  yvals        <- as.numeric(point_grobs$y)
  yvals        <- yvals * panel_height + from_bottom
  xvals        <- xvals * panel_width + from_left
  data.frame(x = xvals/img_dim[1], y = yvals/img_dim[2])
}

Şimdi örneğinizle test edebiliriz:

my.plot <- ggplot(data.frame(x = c(0, 0.456, 1), y = c(0, 0.123, 1))) +
             geom_point(aes(x, y), color = "red")

my.points <- get_x_y_values(my.plot)
my.points
#>           x         y
#> 1 0.1252647 0.1333251
#> 2 0.5004282 0.2330669
#> 3 0.9479917 0.9442339

Ve npc koordinatları olarak değerlerimizi kullanarak, kırmızı noktalarınızın üzerine bazı nokta oyukları çizerek bu değerlerin doğru olduğunu onaylayabiliriz:

my.plot
grid::grid.draw(pointsGrob(x = my.points$x, y = my.points$y, default.units = "npc"))

2020-03-25 tarihinde reprex paketi tarafından oluşturuldu (v0.3.0)


1
Bu sum(to_mm(gt$heights[seq(panel_pos$t - 1)]))kısım en garip olanı. Burada ne topladığınızı açıklar mısınız?
LBogaardt

1
@LBogaardt panel_pos$t, (esnek) panelin oturduğu ızgara sırasını verir, bunun seq(panel_pos$t -1)üzerindeki tüm satır numaraları da bu nedenle sum(to_mm(gt$heights[seq(panel_pos$t - 1)]))bu satırların yüksekliklerinin toplamıdır.
Allan Cameron

@LBgaardt kısalık ve netlik arasında bir denge kurmaya çalışıyordum, ama belki de tam olarak bu hakka sahip değilim ...
Allan Cameron

Ah, bu yüzden bir ggplot bir tablo gibidir, y-etiketi için bir sütun, y-ekseni numaralandırma vb. İçin bir sütun vardır. Aynı şekilde her biri genişlik / yüksekliğe sahip olan satırlar için. Panel bu tablodaki bir hücre mi? Anladım. Teşekkürler Allan.
LBogaardt

1
Aynen, @LBogaardt. Aslında, ggplotGrob bir gTable veya grob tablosu üretir
Allan Cameron
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.